By default, fonts are the highest fingerprinting vector on Firefox. There should be a way to block font fingerprinting and i believe it should be enabled by default.
I am quite happy to report that we agree, and already do this! As part of the Fingerprinting Protection feature we block fonts that are not in the default list for supported OSes, which includes macOS, Windows 10/11, and recent versions of Ubuntu and Fedora.
Fingerprinting Protection is on by default in Private Browsing Mode, and when you have enabled Strict Enhanced Tracking Protection. It's a feature we are working on improving, so we haven't publicized it as much, but as you said - font protection is a high priority item so we work ed on in the first round.
I'm not sure this feature does as it advertises to do? On https://browserleaks.com/fonts with Strict Tracking Protection, the site lists most if not all of my fonts. Only disabling "Allow sites to use their own fonts" seems to prevent a full listing, regardless of the protection level set in Tracking Protection.
The fonts we allow are listed in these files depending on platform. It's not perfect - while these are the standard fonts shipped on these platforms, for one reason or another, we know that some users are just missing some - but not why. On Windows, most if not all of the fonts are restricted from redistribution, so we can't just ship them to you either.
On Browserleaks, if I open the console I see a healthy listing of fonts they try to query that are blocked. So many in fact I can't list them all in this comment, but here's a selection.
Request for font "TeX Gyre Heros" blocked at visibility level 2 (requires 3) fonts
Request for font "Arimo" blocked at visibility level 2 (requires 3) fonts
Request for font "Ubuntu Sans" blocked at visibility level 2 (requires 3) fonts
Request for font "Caladea" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "Carlito" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "cmex10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "cmmi10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "cmr10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "cmsy10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "Courier" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "TeX Gyre Cursor" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "Cousine" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "esint10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "eufm10" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "IPAGothic" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "IPAMincho" blocked at visibility level 2 (requires 3) fonts.js:2:278
Request for font "IPAPGothic" blocked at visibility level 2 (requires 3) fonts.js:2:278
My impression is, the font listing that browserleaks obtains is not obtained from the same method that you block. Not only does the listing of fonts not change regardless of the value of layout.css.font-visibility.* , showing the same ~140 fonts; but as I mentioned only ever disabling "Allow sites to use their own fonts" (which unfortunately is not a site-level setting) reduces the listing to the ~20 or something that one expects to see.
That, or Firefox is seeing all my fonts as "system fonts" (as opposed to "language pack" or "user-installed"), preventing font-visibility from making a proper effect. What *exactly* makes the difference?
"Allow websites to choose their own fonts" corresponds to the `use_documents_fonts` preference, which prevents a website from specifying fonts at all. (It probably allows them to specify a style, like 'mono', 'sans', or 'serif' - I'm not 100% certain.) It makes perfect sense that it would fail to enumerate hardly any fonts on your system when you have that set - it would only be able to enumerate the fonts you've set as your default font. (And even then it will have problems...)
If I unset that checkbox, and set my default fonts to Airmo (serif), Chilanka (sans), and Dyuthi (mono) - browserleaks says I have 77 fonts and 16 unique metrics. Although none are those 3 fonts (which are detected when I have no font protections.) I don't understand why _for certain_ - but I would chalk it up to font detection code being a side channel attack (measuring the size of bounding boxes vs an authoritative "Does the user have this font" API). In support of this theory; if I leave those as my default fonts but re-set the checkbox, allowing websites to choose their own fonts, I go from "415 fonts and 275 unique metrics found" to "419 fonts and 275 unique metrics found". Changing my default font confuses the test to some degree. It probably is not tested well on a set-up where the default font is an unusual one.
layout.css.font-visibility = 3 is equivalent to ETP Standard in Normal Private Browsing; and =2 is equivalent to ETP Standard in PBM. Setting it to 2 changes my Normal browsing window to _almost_ match my PBM Window (it shows 3 fewer fonts). "370 fonts and 237 unique metrics found" vs "367 fonts and 235 unique metrics found" - the =2 setting hides DejaVu Math TeX Gyre, STIXGeneral, and STIX Math which were visible in ETP Standard PBM. That might be a bug, I see a lot of special handling for STIXGeneral in the code; but again - it's a side channel attack so knowing for sure would require reducing the BrowserLeaks test down to a very small understandable test case.
=1 is the same as Resist Fingerprinting mode (I can't say it's the same as Tor Browser, until recently they shipped their own fonts and used an allowlist pref, meaning the behavior in FF and TB was different, but they are changing their implementation slightly and I don't know what version that has or will ship in. Regardless of all that, =1 is a more restrictive mode that hides langpack fonts.) It takes me down to "191 fonts and 109 unique metrics found".
So the values of the pref `layout.css.font-visibility` definetly make a difference in Browserleaks ability to do font fingerprinting. "Use Document Fonts" applies considerable restriction above and beyond that. You didn't mention a platform, but On Mac Levels 2 and 1 are the same - there's no concept of "Lang Pack Fonts" on Mac. On Linux we only have lists for Ubuntu (which is what all my examples were for) and Fedora. I doubt you're on Android, but things get real messy there.
Oh! That was incredibly variegated and useful information that helped me understand things a *lot* more. In particular the note that what a "language pack" is is not "universally" defined, so this allows me to functionally ignore that value when using thre settings (well, setting, one).
"Allow websites to choose their own fonts" corresponds to the `use_documents_fonts` preference, which prevents a website from specifying fonts at all. (It probably allows them to specify a style, like 'mono', 'sans', or 'serif' - I'm not 100% certain.) It makes perfect sense that it would fail to enumerate hardly any fonts on your system when you have that set - it would only be able to enumerate the fonts you've set as your default font. (And even then it will have problems...)
Given this plus the fact that the font-visibility settings are no longer granular: any chance we can get "Allow websites to choose their own fonts" to be a site preference rather than a whole-program (or whole-profile) setting? Maybe for the next ESR or something. It would make it incredibly useful to lower or raise trust settings if basically any site can bypass font detection by far more methods than font enumeration anyway.
That is an interesting idea. I think it would break a lot of things but I can think of one or two places where people might be interested in exploring the tradeoffs. I would suggest filing it as a new issue on Mozilla Connect; as this one is marked as completed and I wouldn't want it to get lost. You can link/reference this discussion for more background. Internally I will keep it in mind and mention it to a few people where it might have a chance, but I also know it would cause a lot of unexpected behavior on the web, so I am not terribly optimistic.
In the interim if you want to do this for yourself, you could use separate profiles to have one with the pref enabled and one with it disabled.