Closed Bug 1937096 Opened 1 year ago Closed 6 months ago

Offscreen canvases don't protect against font fingerprinting

Categories

(Core :: Privacy: Anti-Tracking, defect, P3)

defect

Tracking

()

RESOLVED FIXED
144 Branch
Tracking Status
firefox144 --- fixed

People

(Reporter: fkilic, Assigned: fkilic)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file)

48 bytes, text/x-phabricator-request
Details | Review

Currently, our font protection uses nsPresContext::GetFontVisibility() to determine whether to block a font or not. Most (all?) of our font visibility checks default to FontVisibility::User.

With offscreen canvases, we don't have a prescontext if it is running in a worker thread. CanvasRenderingContext2D::SetFontInternal calls SetFontInternalDisconnected for offscreen canvases, which creates gfxFontGroup with a null prescontext. As a result, we default to user level visibility when finding/resolving fonts.

Edit: I will upload a patch soon.

Attached file (secure)

This is a huge patch, but most of it is refactoring. Here's a summary of how things work:

All the gfx fonts related functions were previously passed nsPresContext* to determine font visibility, reporting blocked fonts to the console, and should resist fingerprinting checks. This patch replaces nsPresContext with FontVisibilityUtils class. It still allows access to nsPresContext if it exists, but other than that, allows us to extend and modify font visibility, reporting to console etc. behaviours.

Similar to how nsPresContext was used throughtout the code, now nsPresContext has a FontVisibilityUtils instance, additionally, CanvasRenderingContext2D instances also have their own FontVisibilityUtils. nsPresContext's FontVisibilityUtil uses presContext's attributes, and canvas's FontVisibilityUtils offscreen canvas's attributes, or canvas element's presContext's attributes.

Hello Emilio! I'm trying to fix this issue, and you were the last person to work on this issue (see bug 1715501). So, just wanted to ni you to let you know, just in case you have some recommendations/objections.

Flags: needinfo?(emilio)

A few thoughts:

  • Having a *Utils class that's instanced is rather odd, most Utils classes are static. Can we come up with a better name? FontVisibilityProvider?
  • Maybe we should just default to user if there's no prescontext. That'd fix this and would be a much smaller patch right?
  • Seems like at the very least the bulk of the refactoring could / should be split to a separate public bug.

Wdyt? Also I'd page in jonathan kew, this should get review from the layout folks at least. Ideally from Jonathan in particular.

Flags: needinfo?(emilio) → needinfo?(fkilic)

Can we come up with a better name? FontVisibilityProvider?

Sure.

We should just default to user if there's no prescontext

This is already the existing behaviour. It allows fingerprinters (see https://abrahamjuliot.github.io/creepjs/tests/fonts.html for example. I have privacy.fingerprintingprotection on and my offscreen canvas fonts are more than the other fonts) to detect available fonts.

Seems like at the very least the bulk of the refactoring could / should be split to a separate public bug.

:tjr asked me to create it as confidential but i think we can make this public after landing it, but up to :tjr.

Also I'd page in jonathan kew

Sure, I'll ni them as well. (I just realized you reviewed the patches and not authored them, sorry)

Flags: needinfo?(fkilic) → needinfo?(jfkthame)

Yeah, as far as the public/confidential bug goes, I didn't know if this would be something we'd be fixing quickly or leaving on file for a long time, and I wanted to keep it semi-private if it was the latter.

Attachment #9443474 - Attachment description: Bug 1937096: Implement FontVisibilityUtils and replace it with nsPresContext passed to gfx/* functions. r?tjr → Bug 1937096: Implement FontVisibilityProvider and replace it with nsPresContext passed to gfx/* functions. r?tjr

FWIW, Tor Browser, which uses the font whitelist, is not affected (you will need to enable OffscreenCanvas) - this is the TextMetricsOffscreen results on creepjs

:jfkthame, would you also have any idea why these tests are failing? https://treeherder.mozilla.org/jobs?repo=try&resultStatus=testfailed%2Cbusted%2Cexception%2Crunnable&revision=0b89e7dba865b82938062bdd3826ce43b3d79f31. I looked at the tests but can't figure out what's causing the issue.

Huh, those failures seem quite strange -- offhand I don't know what would cause that. And this is only happening on Windows, I guess? I'll try build with your patch locally, and see if I can reproduce the problem and investigate a bit. (Feel free to ping me again if I don't come up with anything in the next day or two...)

Flags: needinfo?(jfkthame)

OK, I can confirm that I see similar test failures locally with one of your patches (pulled from tryserver), but it's not immediately obvious what is wrong.

FWIW, I don't think any of the failing tests (as far as I noticed, anyhow) involve offscreen canvas at all, so I think the patch must be inadvertently affecting behavior for "normal" HTML content in some way.

What I would suggest doing here is to split this patch into a series of incremental steps. Start with a no-behavior-change refactoring to introduce the FontVisibilityProvider concept. That can be done in stages: first introduce the new type and pass it to the font code alongside the existing prescontext, and assert that they give the same answers whenever they're used; and only after checking that, then remove the prescontext parameter and rely on the new thing instead.

Once that is in place (and confirmed not to break anything), then start making the changes that actually modify behavior for the offscreen canvas.

That should make it a lot easier to review the changes, and check that the refactoring does not accidentally introduce changes in behavior that were not intended.

Ah it makes sense. Sure I'll try that. Thank you!

In https://phabricator.services.mozilla.com/D97021, some of the failing tests were added. I tried tracing aPresContext uses in nsCanvasFrame but it is so much hahaha. I'll do what you suggested and see if there's some sort of mismatch between values. Thank you!

Severity: -- → S3
Priority: -- → P3

FYI: TB14.5 alpha has moved to using font.vis rather than whitelist (see Bug 1944251 for it's deprecation). So this is now blocking TB from enabling offscreenCanvas. Would be nice to get this for ESR140

I don't know if it helps but I rebased it to central. so it should land nicely. I noticed one thing though, FontFace API doesn't protect against fingerprinting in workers. I think tor disables it completely though, so for Tor it should be fine

(In reply to Fatih Kilic [:fkilic] from comment #12)

I don't know if it helps but I rebased it to central. so it should land nicely. I noticed one thing though, FontFace API doesn't protect against fingerprinting in workers. I think tor disables it completely though, so for Tor it should be fine

Font whitelisting disables FontFace, but we're switching to font visibility, so 14.5 will have FontFace enabled.

See Also: → 1960446

welp then we should fix it too

Blocks: 1960446
Attachment #9443474 - Attachment description: Bug 1937096: Implement FontVisibilityProvider and replace it with nsPresContext passed to gfx/* functions. r?tjr → (secure)
Group: mozilla-employee-confidential
QA Whiteboard: [qa-triage-done-c145/b144]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: