Opened 6 years ago

Last modified 23 months ago

#5798 new defect

Improve persistence and WebFont compatibility of font patch

Reported by: mikeperry Owned by: tbb-team
Priority: High Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: tbb-fingerprinting-fonts, interview, tbb-testcase, tbb-firefox-patch
Cc: gk, arthuredelstein@…, dcf@…, Peter_Baumann_TUD Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Sid Stamm reviewed my font count limiting patch and suggested that the nsPrefShell is the wrong place to store font counts, since it may be cleared in circumstances such as refreshes/redirects. We probably want something that has a similar lifetime to cookies.. Perhaps the Content Prefs database?

Additionally, we should be passing a bit down to prevent the font limits from applying to remotely-sourced WebFonts (from @font-face).

Child Tickets

Change History (25)

comment:1 Changed 6 years ago by gk

Cc: g.koppen@… added

comment:2 Changed 5 years ago by mikeperry

Keywords: tbb-fingerprinting added

comment:3 Changed 5 years ago by mikeperry

It's also possible to induce fallback to the default system font, which may reveal OS info:
http://eb0b428b.byethost7.com/screen.html (copy of that source is attached to #6786).

Not sure if that is worth special casing or not. It may be hard to conceal OS given access to a dozen fonts, and there are likely to be ways to infer OS through other vectors.

comment:4 Changed 5 years ago by mikeperry

Keywords: interview added

comment:5 Changed 5 years ago by monkeyiq

Looking over the patch, perhaps nsPrefShell refers to the nsPresContext where the mFontsUsed/mFontsTried member variables track the font use/attempts.

Looking over the docs for nsIContentPrefService the use of the new
GetFirstPartyURI() function gets us the "group"/url first param to SetPref(). Looking over what a variant can take (NsIVariant) it seems limited to strings and basic numeric types. So much for the perhaps bad idea of marshalling a stringset (font names used) into a single value there.

I'm thinking that maybe using some canonical marshalling of the nsfont to a single string (eg, font.name from the current patch, maybe investigate adding style later too) and an aName (the key part for the pref) in the nsIContentPrefService of "tor.FontAttempt.${font.name}" and just setting the value to 1.
Also using a prefix like "tor.FontAttempts" to record when a new fontattempt is made that isn't already in the prefs. So a probe to see if a font.name is new is quick, and the total number of used fonts or probes is also quick.

Though there is some memory overhead using a new Content Prefs entry for each probe/use of a font for a site. Perhaps an acceptable trade of some RAM bits for less exposed entropy bits though.

comment:6 Changed 5 years ago by mikeperry

Parent ID: #7248

Ben: Are you still interested in finishing this up? As I said in my email to you, the approach seems good, and if we get something that works in a clean git patch against Firefox 17-ESR, we'll merge it and are still fine with you invoicing for the work.

comment:7 Changed 5 years ago by monkeyiq

mike: definitely still interested. I just dusted the code off and ran it through the tbb hookup, to do a round of testing against flippingtypical. Alas... it seems that site can only detect 1 font. I then tested the normal tbb and it only finds a single font there too. Using plain Firefox allows flipping to find many fonts, so it seems that something in the current normal tbb release is stopping flipping from probing.

fwiw installing tbb on osx mountain lion gives me the same result: only 1 font detected. Regular Firefox on osx sees 60+ fonts.

So I'll have to find a nastier prober before I can test the patch for final delivery :|

comment:8 Changed 5 years ago by monkeyiq

Also FWIW the base site that flipping links to:
http://www.lalit.org/lab/javascript-css-font-detect/
says that every font is detected with run in tbb, but works properly when run in bare firefox.

comment:9 Changed 5 years ago by mikeperry

From your description, it sounds like both patches are functioning properly for the flippingtypical test. The only thing the preferences system is supposed to give us is to prevent redirects/refreshes from zeroing the font probe list (allowing new fonts to be probed after the reload).

The second site is a little concerning, but could be because we cause a different fallback than the generic face they expect when they hit our limit. Possibly a separate bug.

However, there is a third test I'd ideally want to work here, but to be honest it's one I couldn't immediately find how to do in the codebase myself. I want webfonts *not* to count towards your total, so that if a website uses @font-face to source 10 remote fonts, those are not counted towards this limit. At first, I thought I could simply set a bit in nsFont when these fonts were loaded, and check for the bit in the CSS rule loader, but it didn't seem to be that straight-forward and/or I was missing some crucial detail where @font-face rules get converted into nsFonts.

If you can figure out where that is actually happening, we'd pay for that time too.

Note that our default NoScript configuration blocks WebFonts. You'd need to go into NoScript Options->Embeddings and uncheck "Forbid @font-face" to test.

The PDF.JS extension (https://addons.mozilla.org/en-US/firefox/addon/pdfjs) is a good test. It uses @font-face internally for the fonts provided by the document, and most PDFs are visibly damaged by our font limits inappropriately applying to those document fonts.

comment:10 Changed 5 years ago by mikeperry

Dug down this rabbit hole a bit more. If we could just call nsRuleNode::mFont->GetType(), we could check the type for FONT_FACE_RULE. But we can't due to unknown concrete type of mFont.. We might be able to QI to nsIDOMCSSRule and use GetType(), but I think that might actually be mFont->mDOMRule.type, not mFont->type. This has the same problem...

I'll try grepping the source for more instances of FONT_FACE_RULE later.. Maybe there are other places where it gets copied to something we can inspect from nsRuleNode. Need to switch back to trying to salvage FF17 right now.

comment:11 Changed 5 years ago by mikeperry

Alright! I finally figured out the @font-face piece of this, no need to worry about it. The updated version of the font liming patch should be at https://gitweb.torproject.org/mikeperry/torbrowser.git/blob/bug3944-intlfixes:/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch. It should be merged into origin/maint-2.4 shortly.

comment:12 Changed 5 years ago by mikeperry

Parent ID: #7248

I moved the @font-face exemption to #8270.

comment:13 Changed 4 years ago by gacar

It seems keeping font counts in nsPresContext allows a page to circumvent font-limits by using multiple frames: http://jsbin.com/uRidOyAg/1

I guess this is because each frame has it's own presentation context.

The demo uses font-face rules to make it easier to test (e.g. NSPR_LOG_MODULES=timestamp,userfonts:5). The attack also works with plain CSS font-family rules.

Last edited 4 years ago by gacar (previous) (diff)

comment:14 Changed 4 years ago by mikeperry

Keywords: tbb-testcase added

Sweet. A test case.

comment:15 Changed 4 years ago by gk

Marked #12150 as a duplicate of this one. Some testcode added there can be found on http://pastebin.com/raw.php?i=D8DWb47X and http://pastebin.com/raw.php?i=MkqVQv8x.

comment:16 Changed 4 years ago by arthuredelstein

Cc: arthuredelstein@… added

comment:17 Changed 4 years ago by gk

Cc: gk added; g.koppen@… removed

comment:18 Changed 3 years ago by dcf

Cc: dcf@… added

comment:19 Changed 3 years ago by erinn

Keywords: tbb-firefox-patch added

comment:20 Changed 3 years ago by erinn

Component: Firefox Patch IssuesTor Browser
Owner: changed from mikeperry to tbb-team

comment:21 in reply to:  description Changed 3 years ago by arthuredelstein

Replying to mikeperry:

Sid Stamm reviewed my font count limiting patch and suggested that the nsPrefShell is the wrong place to store font counts, since it may be cleared in circumstances such as refreshes/redirects. We probably want something that has a similar lifetime to cookies. Perhaps the Content Prefs database?

After #5752 lands, each URL-bar domain will be assigned a separate identity. So perhaps a good approach would be to maintain a font-limit for each Tor identity (URL-bar domain). I hope that would counter the multi-frame circumvention in comment:13.

comment:22 Changed 3 years ago by arthuredelstein

An interesting font detector demonstration:
http://www.lalit.org/lab/javascript-css-font-detect/

comment:23 Changed 3 years ago by mikeperry

Keywords: tbb-fonts added

comment:24 Changed 3 years ago by gk

Cc: Peter_Baumann_TUD added

#14560 is as duplicate of this (see another test script attached there).

comment:25 Changed 23 months ago by bugzilla

Keywords: tbb-fingerprinting-fonts added; tbb-fingerprinting tbb-fonts removed
Severity: Normal
Note: See TracTickets for help on using tickets.