|
1 |
| -# Explainer for the TODO API |
| 1 | +# Limiting Access to Local Fonts |
2 | 2 |
|
3 |
| -**Instructions for the explainer author: Search for "todo" in this repository and update all the |
4 |
| -instances as appropriate. For the instances in `index.bs`, update the repository name, but you can |
5 |
| -leave the rest until you start the specification. Then delete the TODOs and this block of text.** |
| 3 | +This proposal is an early design sketch by Chrome to describe the problem below and solicit feedback on the proposed solution. It has not been approved to ship in Chrome. |
6 | 4 |
|
7 |
| -This proposal is an early design sketch by [TODO: team] to describe the problem below and solicit |
8 |
| -feedback on the proposed solution. It has not been approved to ship in Chrome. |
9 | 5 |
|
10 |
| -TODO: Fill in the whole explainer template below using https://tag.w3.org/explainers/ as a |
11 |
| -reference. Look for [brackets]. |
| 6 | +## Authors |
12 | 7 |
|
13 |
| -## Proponents |
| 8 | +[Tanushree Bisht](https://github.com/tanushreebisht) |
| 9 | + |
| 10 | +[Zainab Rizvi](https://github.com/zainabaq) |
14 | 11 |
|
15 |
| -- [Proponent team 1] |
16 |
| -- [Proponent team 2] |
17 |
| -- [etc.] |
18 | 12 |
|
19 | 13 | ## Participate
|
20 |
| -- https://github.com/explainers-by-googlers/[your-repository-name]/issues |
21 |
| -- [Discussion forum] |
22 |
| - |
23 |
| -## Table of Contents [if the explainer is longer than one printed page] |
24 |
| - |
25 |
| -<!-- Update this table of contents by running `npx doctoc README.md` --> |
26 |
| -<!-- START doctoc generated TOC please keep comment here to allow auto update --> |
27 |
| -<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
28 |
| - |
29 |
| -- [Introduction](#introduction) |
30 |
| -- [Goals](#goals) |
31 |
| -- [Non-goals](#non-goals) |
32 |
| -- [User research](#user-research) |
33 |
| -- [Use cases](#use-cases) |
34 |
| - - [Use case 1](#use-case-1) |
35 |
| - - [Use case 2](#use-case-2) |
36 |
| -- [[Potential Solution]](#potential-solution) |
37 |
| - - [How this solution would solve the use cases](#how-this-solution-would-solve-the-use-cases) |
38 |
| - - [Use case 1](#use-case-1-1) |
39 |
| - - [Use case 2](#use-case-2-1) |
40 |
| -- [Detailed design discussion](#detailed-design-discussion) |
41 |
| - - [[Tricky design choice #1]](#tricky-design-choice-1) |
42 |
| - - [[Tricky design choice 2]](#tricky-design-choice-2) |
43 |
| -- [Considered alternatives](#considered-alternatives) |
44 |
| - - [[Alternative 1]](#alternative-1) |
45 |
| - - [[Alternative 2]](#alternative-2) |
46 |
| -- [Stakeholder Feedback / Opposition](#stakeholder-feedback--opposition) |
47 |
| -- [References & acknowledgements](#references--acknowledgements) |
48 |
| - |
49 |
| -<!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| 14 | +[https://github.com/explainers-by-googlers/limiting-local-fonts-access/issues](https://github.com/explainers-by-googlers/limiting-local-fonts-access/issues) |
50 | 15 |
|
51 | 16 | ## Introduction
|
| 17 | +The specific set of fonts available locally on a device is somewhat unique, as different users install different software with different configurations, language support, etc. It is possible to determine which fonts a user has installed locally by measuring the side-effects of font rendering, and these techniques are widely relied-upon as a core component of scripts that aim to re-identify users cross-context. |
| 18 | + |
| 19 | +To limit its utility for re-identification of the browser or device, we propose reducing the number of local fonts that a webpage can load by limiting the returned list of fonts to default system fonts shipped by the operating system. |
52 | 20 |
|
53 |
| -[The "executive summary" or "abstract". |
54 |
| -Explain in a few sentences what the goals of the project are, |
55 |
| -and a brief overview of how the solution works. |
56 |
| -This should be no more than 1-2 paragraphs.] |
57 | 21 |
|
58 | 22 | ## Goals
|
| 23 | +* Ensure that the same list of fonts is used for all users on a platform |
| 24 | +* Address the various ways user-installed fonts can be accessed, including CSS `font-family`, CSS `@font-face` and Canvas text rendering |
| 25 | +* Allow users to grant access to all locally-installed fonts to specific origins using the [Local Font Access API](https://developer.chrome.com/docs/capabilities/web-apis/local-fonts) |
| 26 | + |
59 | 27 |
|
60 |
| -[What is the **end-user need** which this project aims to address? Make this section short, and |
61 |
| -elaborate in the Use cases section.] |
62 | 28 |
|
63 | 29 | ## Non-goals
|
| 30 | +* This document does not propose solutions for platforms that have varied or customizable font packages, such as Linux, for which it is difficult to build an allowlist of platform fonts due to its wide range of distributions that tailor to varying user preferences |
| 31 | +* The intervention proposed here only impacts the availability of locally-installed fonts; web developers can continue to load fonts from the web as they do presently |
| 32 | + |
| 33 | + |
| 34 | +## Overview |
| 35 | + |
| 36 | + |
| 37 | +### Context |
64 | 38 |
|
65 |
| -[If there are "adjacent" goals which may appear to be in scope but aren't, |
66 |
| -enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.] |
| 39 | +#### Motivation |
67 | 40 |
|
68 |
| -## User research |
| 41 | +The CSS Working Group has had [ongoing discussions](https://github.com/w3c/csswg-drafts/issues/11775) over limiting the availability of local fonts in such a way that would not break the web and disproportionately impact users who use less common languages. |
69 | 42 |
|
70 |
| -[If any user research has been conducted to inform your design choices, |
71 |
| -discuss the process and findings. User research should be more common than it is.] |
| 43 | +[Recent CSSWG discussions](https://github.com/w3c/csswg-drafts/issues/11753) have brought up the idea of prescribing user agents to not expose user-installed fonts on the web as a privacy protecting measure. These measures mirror [Safari’s approach](https://webkit.org/tracking-prevention/) of limiting local font availability by restricting to fonts that are bundled with the operating system by default. |
72 | 44 |
|
73 |
| -## Use cases |
74 | 45 |
|
75 |
| -[Describe in detail what problems end-users are facing, which this project is trying to solve. A |
76 |
| -common mistake in this section is to take a web developer's or server operator's perspective, which |
77 |
| -makes reviewers worry that the proposal will violate [RFC 8890, The Internet is for End |
78 |
| -Users](https://www.rfc-editor.org/rfc/rfc8890).] |
| 46 | +#### Background |
79 | 47 |
|
80 |
| -### Use case 1 |
| 48 | +##### How fonts are used to track users |
81 | 49 |
|
82 |
| -### Use case 2 |
| 50 | +Websites may be able to detect the set of fonts installed on a user’s system, which, in combination with other signals, can be used to re-identify a browser across contexts. |
83 | 51 |
|
84 |
| -<!-- In your initial explainer, you shouldn't be attached or appear attached to any of the potential |
85 |
| -solutions you describe below this. --> |
| 52 | +One of them involves the Canvas API. A particular font can be used to draw text onto a `<canvas>` element. The resulting pixel data can be analyzed via `canvas.measureText()` and compared against known sizes of rendered Canvases from reference fonts. |
86 | 53 |
|
87 |
| -## [Potential Solution] |
| 54 | +Websites can also detect whether a font is installed on a system by rendering text using a font whose existence is being checked, measuring the width of its `<span>`, and comparing it with those of generic fallback fonts. If the widths differ, the font is considered present on the user’s system; otherwise, it is assumed to be missing. |
88 | 55 |
|
89 |
| -[For each related element of the proposed solution - be it an additional JS method, a new object, a new element, a new concept etc., create a section which briefly describes it.] |
90 | 56 |
|
91 |
| -```js |
92 |
| -// Provide example code - not IDL - demonstrating the design of the feature. |
| 57 | +### Implementation |
93 | 58 |
|
94 |
| -// If this API can be used on its own to address a user need, |
95 |
| -// link it back to one of the scenarios in the goals section. |
| 59 | +#### Current state |
96 | 60 |
|
97 |
| -// If you need to show how to get the feature set up |
98 |
| -// (initialized, or using permissions, etc.), include that too. |
99 |
| -``` |
| 61 | +[Blink’s font matching mechanism](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/platform/fonts/README.md) makes use of system fonts when needed by selecting glyphs based on various characteristics, such as desired fonts, language and character set. It employs [font fallback](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/platform/fonts/README.md#font-fallback) and caching mechanisms to accurately render text across various platforms. |
100 | 62 |
|
101 |
| -[Where necessary, provide links to longer explanations of the relevant pre-existing concepts and API. |
102 |
| -If there is no suitable external documentation, you might like to provide supplementary information as an appendix in this document, and provide an internal link where appropriate.] |
| 63 | +Local fonts can be accessed via the following methods: |
103 | 64 |
|
104 |
| -[If this is already specced, link to the relevant section of the spec.] |
| 65 | +* CSS [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) property |
| 66 | +* [local() src](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#localfont-face-name) to CSS [@font-face rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face) |
| 67 | +* [CanvasRenderingContext2D.font](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font) property |
| 68 | +* [Local Fonts Access API](https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API) |
105 | 69 |
|
106 |
| -[If spec work is in progress, link to the PR or draft of the spec.] |
| 70 | +#### Intervention |
107 | 71 |
|
108 |
| -[If you have more potential solutions in mind, add ## Potential Solution 2, 3, etc. sections.] |
| 72 | +Initially, user-installed fonts specified via the CSS [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) property, [local() src](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#localfont-face-name) for the CSS [@font-face rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face), and [CanvasRenderingContext2D.font](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font) property may be blocked from rendering. |
109 | 73 |
|
110 |
| -### How this solution would solve the use cases |
| 74 | +Multiple ways of implementing this approach have been explored. A potential approach is to build and maintain lists of the fonts that various platforms install by default, and to use those lists as sources of truth when determining whether a font is considered user-installed and thus filtered from font selection. |
111 | 75 |
|
112 |
| -[If there are a suite of interacting APIs, show how they work together to solve the use cases described.] |
| 76 | +Windows and macOS could be the first platforms that we limit the availability of user-installed fonts on as they have officially published the lists of the fonts they install by default. For each platform and platform version, we will use the flat lists of OS-installed font faces that are published online for a base OS version: |
113 | 77 |
|
114 |
| -#### Use case 1 |
| 78 | +* [Windows 10 fonts list](https://learn.microsoft.com/en-us/typography/fonts/windows_10_font_list) to encompass Windows 10/11 |
| 79 | +* [macOS 13 Ventura fonts list](https://support.apple.com/en-us/103197) to encompass macOS 13/14/15 |
115 | 80 |
|
116 |
| -[Description of the end-user scenario] |
| 81 | +The OS-shipped fonts lists sourced from above will be stored in binary itself or loaded at browser startup time (for easier list updates) during the experimentation phase. In later phases, we may consider delivering the OS-shipped fonts lists to Chrome via more automated and maintainable approaches, as well as storing more granular lists per platform version. |
117 | 82 |
|
118 |
| -```js |
119 |
| -// Sample code demonstrating how to use these APIs to address that scenario. |
120 |
| -``` |
| 83 | +We will start off by filtering user-installed fonts from being accessed via the `font-family` CSS property, as that is the most common way developers specify what fonts they wish to use to render text on their webpages. We will also collect impact metrics in related codepaths. Filtering will be activated during the font selection process when: |
121 | 84 |
|
122 |
| -#### Use case 2 |
| 85 | +1. The operating system of the user agent is either macOS or Windows |
| 86 | +2. The user has not given prior [permission](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy/local-fonts) to access their local fonts on an origin via the [Local Fonts Access API](https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API) |
123 | 87 |
|
124 |
| -[etc.] |
| 88 | +#### Analysis |
125 | 89 |
|
126 |
| -## Detailed design discussion |
| 90 | +By running an experiment with the intervention as outlined above, we can get a headstart on quantifying impacts of the filtering of user-installed fonts. We are interested in collecting metrics on the following data points: |
127 | 91 |
|
128 |
| -### [Tricky design choice #1] |
| 92 | +* Font fallback rates |
| 93 | + * How often we have to select the last resort font when the intervention is enabled. |
| 94 | +* Performance impacts of the intervention |
| 95 | + * The lookup of whether a font is considered a system font in various codepaths in the fonts codebase will add latency to the font selection mechanism. |
| 96 | +* Less common languages which may have limited font support |
| 97 | + * These are less common languages and/or languages that have complex or rare scripts that may not often be bundled with the operating systems at install-time, which users may have to manually install on their devices. Local font filtering may disproportionately result in users of such languages having issues with text rendering. |
129 | 98 |
|
130 |
| -[Talk through the tradeoffs in coming to the specific design point you want to make.] |
| 99 | +From the analysis on the metrics collected during the experimentation phase, we may look into adjusting the list of fonts we include in the shipped lists to get better character coverage over less frequently used languages on the web. |
131 | 100 |
|
132 |
| -```js |
133 |
| -// Illustrated with example code. |
134 |
| -``` |
| 101 | +### Future Improvements |
135 | 102 |
|
136 |
| -[This may be an open question, |
137 |
| -in which case you should link to any active discussion threads.] |
| 103 | +Longer term, we may investigate providing a consistent, limited set of fonts (a "synthetic font environment"), based on existing corpuses. This approach has challenges in terms of distribution, as a full set of fonts would mean a sizable download. We hope insights gained from implementing this current proposal, which limits access to default system fonts, would be valuable in exploring the feasibility and design of such a system. |
138 | 104 |
|
139 |
| -### [Tricky design choice 2] |
| 105 | +While we initially aim to ship in Incognito mode, we are evaluating limiting font access to all browsing sessions as a platform-hardening measure. This could potentially involve allowing access to a small, curated list of common fonts beyond system defaults or limiting access to a numerical threshold of locally-installed fonts. |
140 | 106 |
|
141 |
| -[etc.] |
| 107 | +## FAQs |
142 | 108 |
|
143 |
| -## Considered alternatives |
| 109 | +### Limiting to local fonts will break my application, what should I do? |
144 | 110 |
|
145 |
| -[This should include as many alternatives as you can, |
146 |
| -from high level architectural decisions down to alternative naming choices.] |
| 111 | +Does your application specifically need access to user-installed local fonts? If so, consider switching to the [Local Font Access API](https://developer.chrome.com/docs/capabilities/web-apis/local-fonts#the_local_font_access_api) which will always be honored with this proposal. If your use case falls outside this, we would like to consider it, so please file an issue. |
147 | 112 |
|
148 |
| -### [Alternative 1] |
| 113 | +### |
| 114 | +How will font lists be maintained? |
149 | 115 |
|
150 |
| -[Describe an alternative which was considered, |
151 |
| -and why you decided against it.] |
| 116 | +We have decided to focus on Windows and MacOS because font lists are readily available and easier to compile ([macOS](https://support.apple.com/en-us/103197), [Windows](https://learn.microsoft.com/en-us/typography/fonts/windows_10_font_list)). For these platforms, we expect to update the list with each major platform release. Ensuring accurate and up-to-date lists will require collaboration with the platform owners in terms of them continuing to share their lists or opening up access to APIs that reliably expose their lists of default OS-shipped fonts. |
152 | 117 |
|
153 |
| -### [Alternative 2] |
| 118 | +### Are there plans to introduce this to other platforms? |
154 | 119 |
|
155 |
| -[etc.] |
| 120 | +We are starting with Windows and MacOS because of the ease of availability of font lists. |
156 | 121 |
|
157 |
| -## Stakeholder Feedback / Opposition |
| 122 | +For Linux, it’s difficult to come up with a common denominator list of OS-shipped fonts because of its wide range of distributions. Linux distributions are customized to fit different target needs and audiences, which can lead to variances in default font packages and flavors. For example, distributions may vary in their default Unicode coverage based on the target audience, and thus tailor their default font packages to specific locales. |
158 | 123 |
|
159 |
| -[Implementors and other stakeholders may already have publicly stated positions on this work. If you can, list them here with links to evidence as appropriate.] |
| 124 | +Android is also not considered in the initial intervention as Android ships with a limited set of fonts that are controlled by the OS/device manufacturer and does not commonly rely on user-installed fonts. However, fonts via `src: local()` matching may still present identifiable information on Android devices based on variations in available fonts and OEM configurations. |
160 | 125 |
|
161 |
| -- [Implementor A] : Positive |
162 |
| -- [Stakeholder B] : No signals |
163 |
| -- [Implementor C] : Negative |
| 126 | +In an ideal world, the user agent is not responsible for maintaining font lists because the OS would provide an API that exposes what fonts are considered OS-defaults. |
164 | 127 |
|
165 |
| -[If appropriate, explain the reasons given by other implementors for their concerns.] |
| 128 | +## Security and privacy considerations |
166 | 129 |
|
167 |
| -## References & acknowledgements |
| 130 | +The goal of limiting local fonts is to reduce information available that can be used to re-identify the user across sites, so we expect this proposal to be privacy-positive. Though limiting font availability to OS-installed fonts can expose the user’s platform and potentially the major version, we accept this because user agent headers already make this information available. |
168 | 131 |
|
169 |
| -[Your design will change and be informed by many people; acknowledge them in an ongoing way! It helps build community and, as we only get by through the contributions of many, is only fair.] |
| 132 | +## Contributors and Acknowkedgements |
170 | 133 |
|
171 |
| -[Unless you have a specific reason not to, these should be in alphabetical order.] |
| 134 | +[Antonio Sartori](https://github.com/antosart) |
172 | 135 |
|
173 |
| -Many thanks for valuable feedback and advice from: |
| 136 | +[Dominik Röttsches](https://github.com/drott) |
174 | 137 |
|
175 |
| -- [Person 1] |
176 |
| -- [Person 2] |
177 |
| -- [etc.] |
| 138 | +[Mike West](https://github.com/mikewest) |
0 commit comments