Opened 10 months ago

Last modified 16 hours ago

#26607 new defect

verify that subpixel accuracy of window scroll properties does not add fingerprinting risk

Reported by: mcs Owned by: tbb-team
Priority: High Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: tbb-fingerprinting, ff60-esr, TorBrowserTeam201904
Cc: arthuredelstein Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

​As of Firefox 55, the window.pageYOffset, pageXOffset, scrollX, and scrollY properties now return data with subpixel accuracy. We think this means "half pixels on a macOS Retina or other high resolution display." We should determine if this adds any fingerprinting risks (and whether the values returned are already rounded when privacy.resistFingerprinting is set to true). See:

https://bugzilla.mozilla.org/show_bug.cgi?id=1151421

Child Tickets

Change History (22)

comment:1 Changed 10 months ago by arthuredelstein

Cc: arthuredelstein added

comment:2 Changed 10 months ago by gk

Priority: MediumImmediate

Bumping prio.

comment:3 Changed 10 months ago by gk

Priority: ImmediateHigh

comment:4 Changed 9 months ago by gk

Keywords: TorBrowserTeam201808 added; TorBrowserTeam201807 removed

Move our tickets to August.

comment:5 Changed 8 months ago by gk

Keywords: TorBrowserTeam201809 added; TorBrowserTeam201808 removed

Moving our tickets to September 2018

comment:6 Changed 7 months ago by gk

Keywords: TorBrowserTeam201810 added; TorBrowserTeam201809 removed

Moving tickets to October

comment:7 Changed 6 months ago by gk

Keywords: TorBrowserTeam201811 added; TorBrowserTeam201810 removed

Moving our tickets to November.

comment:8 Changed 5 months ago by gk

Keywords: TorBrowserTeam201812 added; TorBrowserTeam201811 removed

Moving our tickets to December.

comment:9 Changed 3 months ago by gk

Keywords: TorBrowserTeam201901 added; TorBrowserTeam201812 removed

Moving tickets to Jan 2019.

comment:10 Changed 3 months ago by gk

Keywords: TorBrowserTeam201902 added; TorBrowserTeam201901 removed

Moving tickets to February.

comment:11 Changed 7 weeks ago by gk

Keywords: TorBrowserTeam201903 added; TorBrowserTeam201902 removed

Moving remaining tickets to March.

comment:12 Changed 3 weeks ago by gk

Keywords: TorBrowserTeam201904 added; TorBrowserTeam201903 removed

Moving tickets to April.

comment:13 Changed 2 weeks ago by Thorin

We think this means "half pixels on a macOS Retina or other high resolution display."

See [1], you need to scroll up and down for a tiny bit. Tests records up to 100 edit: 50 scrollX values - as it gets a value, it checks if it is an integer - if it is, it continues, if not, then it stops the test. Last value is display and logic for sub-pixel detection (yes/no)

On my ancient Android 6, I get half pixels. If I zoom it and refresh I get 13 decimal places. I don't have a Mac or retina display.

I suggest we file an issue for Tor Uplift to round sub-pixels to an integer when RFP = true

[1] https://thorin-oakenpants.github.io/testing/

Last edited 2 weeks ago by Thorin (previous) (diff)

comment:14 Changed 2 weeks ago by gk

Summary: verify that subpixel accuracy of window scroll properties does not add fingerprinting riskRound subpixel accuracy of window (scroll) properties

Thanks for the investigation, I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1542676 for the Moz bug. Adjusting the title of the bug.

comment:15 Changed 2 weeks ago by Thorin

Summary: Round subpixel accuracy of window (scroll) propertiesverify that subpixel accuracy of window scroll properties does not add fingerprinting risk

I added a reset button. Zoom is "wonky". If you zoom AFTER loading the page you get a gazillion decimal places. But if you zoom the tab before loading the page, then it seems to stick to .5's (or whole numbers)

comment:16 Changed 2 weeks ago by Thorin

FYI: I added a test to window.scrollTo(0, 500.5) and read back the position, and it doesn't throw any errors and rounds to an integer (tested on my Android). Are there any other methods that need testing?

comment:17 Changed 2 weeks ago by gk

Not sure, I guess only the new methods that got added by https://bugzilla.mozilla.org/show_bug.cgi?id=1151421 for now.

comment:18 Changed 7 days ago by acat

This is leaking the actual window.devicePixelRatio (always set to 1 with resistfingerprinting), which is 2 on retina and varies a bit on the Android devices I tested (2.77, 3). POC: https://acatarineu.github.io/fp/devicePixelRatio.html. In normal desktop screens it can be simulated by changing the zoom and refreshing the page.

I think it's not exclusive of the scroll properties, the same subpixel values can be seen with elem.getBoundingClientRect() and probably others. I need to read more about the implementation to see what's the best way of fixing this.

comment:19 in reply to:  18 Changed 7 days ago by Thorin

Replying to acat:

This is leaking the actual window.devicePixelRatio (always set to 1 with resistfingerprinting)

Nice PoC! Added window.devicePixelRatio (DRP) output to my test to make things easy, and some tests

my Android: RFP=true
[1] subpixel: .5, dpr: 1
[2] window=1 guessed=2

my Android: RFP=false (I restarted the device)
[1] subpixel: .5, dpr: 2
[2] window=2 guessed=2

So you're extrapolating the DPR based on scroll because scroll (among others) uses DPR in it's calculations, and DPR spoofing doesn't allow for that?

Original DPR spoof upstream ticket from Arthur: https://bugzilla.mozilla.org/show_bug.cgi?id=418986#c50

[1] https://thorin-oakenpants.github.io/testing/
[2] https://acatarineu.github.io/fp/devicePixelRatio.html

comment:20 Changed 25 hours ago by Thorin

more from Arthur, including an old patch/solution: https://bugzilla.mozilla.org/show_bug.cgi?id=1216800 "some chrome code may be incorrectly receiving spoofed devicePixelRatio"

comment:21 in reply to:  20 ; Changed 22 hours ago by acat

Replying to Thorin:

more from Arthur, including an old patch/solution: https://bugzilla.mozilla.org/show_bug.cgi?id=1216800 "some chrome code may be incorrectly receiving spoofed devicePixelRatio"

Thanks, although I think that one refers to the fact that devicePixelRatio should not be spoofed internally in Firefox privileged pages. Here the problem is that it can be guessed in normal pages (via some side-channels) and it should not.

Perhaps this one could be closed as duplicate of #29564, since everything that can be measured via window.scrollXY can also be obtained via document.body.getBoundingClientRect() or similar.

For the concrete case of using the scroll+(getClientRects or scrollY) to guess the real window.devicePixelRatio, I do not see a good solution. Rounding values does not solve it completely because it should be possible to slowly nudge elements to guess the actual subpixel value (as suggested by @tom in an email). Another possibility could be to make sure scroll is done in "CSS pixels" (currently scroll seems to be done in "physical pixels", 1 scroll pixel is 1/devicePixelRatio CSS pixels, and that's where the measured subpixel values come from). If we think this is critical enough perhaps the effort might be justified, but not sure.

comment:22 in reply to:  21 Changed 16 hours ago by gk

Replying to acat:

Replying to Thorin:

more from Arthur, including an old patch/solution: https://bugzilla.mozilla.org/show_bug.cgi?id=1216800 "some chrome code may be incorrectly receiving spoofed devicePixelRatio"

Thanks, although I think that one refers to the fact that devicePixelRatio should not be spoofed internally in Firefox privileged pages. Here the problem is that it can be guessed in normal pages (via some side-channels) and it should not.

Perhaps this one could be closed as duplicate of #29564, since everything that can be measured via window.scrollXY can also be obtained via document.body.getBoundingClientRect() or similar.

It seems to me the subpixel issue is just one of a bunch of factors that make it possible to use DOMRect etc. for fingerprinting, no? In that case it's not really a duplicate, more a child bug if we want.

For the concrete case of using the scroll+(getClientRects or scrollY) to guess the real window.devicePixelRatio, I do not see a good solution. Rounding values does not solve it completely because it should be possible to slowly nudge elements to guess the actual subpixel value (as suggested by @tom in an email). Another possibility could be to make sure scroll is done in "CSS pixels" (currently scroll seems to be done in "physical pixels", 1 scroll pixel is 1/devicePixelRatio CSS pixels, and that's where the measured subpixel values come from). If we think this is critical enough perhaps the effort might be justified, but not sure.

Hm. I'd not be opposed to test the latter. However, maybe we could ni? some knowledgeable Mozilla folks on bug 1542676 (or a more appropriate one, if there is any), asking whether that's a smart idea or what else we should do here?

Note: See TracTickets for help on using tickets.