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).
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
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.
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.
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.
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 :|
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.
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.
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.