Opened 15 months ago

Last modified 5 months 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 (24)

comment:1 Changed 15 months ago by arthuredelstein

Cc: arthuredelstein added

comment:2 Changed 15 months ago by gk

Priority: MediumImmediate

Bumping prio.

comment:3 Changed 15 months ago by gk

Priority: ImmediateHigh

comment:4 Changed 14 months ago by gk

Keywords: TorBrowserTeam201808 added; TorBrowserTeam201807 removed

Move our tickets to August.

comment:5 Changed 13 months ago by gk

Keywords: TorBrowserTeam201809 added; TorBrowserTeam201808 removed

Moving our tickets to September 2018

comment:6 Changed 12 months ago by gk

Keywords: TorBrowserTeam201810 added; TorBrowserTeam201809 removed

Moving tickets to October

comment:7 Changed 11 months ago by gk

Keywords: TorBrowserTeam201811 added; TorBrowserTeam201810 removed

Moving our tickets to November.

comment:8 Changed 9 months ago by gk

Keywords: TorBrowserTeam201812 added; TorBrowserTeam201811 removed

Moving our tickets to December.

comment:9 Changed 8 months ago by gk

Keywords: TorBrowserTeam201901 added; TorBrowserTeam201812 removed

Moving tickets to Jan 2019.

comment:10 Changed 7 months ago by gk

Keywords: TorBrowserTeam201902 added; TorBrowserTeam201901 removed

Moving tickets to February.

comment:11 Changed 6 months ago by gk

Keywords: TorBrowserTeam201903 added; TorBrowserTeam201902 removed

Moving remaining tickets to March.

comment:12 Changed 6 months ago by gk

Keywords: TorBrowserTeam201904 added; TorBrowserTeam201903 removed

Moving tickets to April.

comment:13 Changed 5 months 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 5 months ago by Thorin (previous) (diff)

comment:14 Changed 5 months 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 5 months 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 5 months 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 5 months 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 5 months 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 5 months 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 5 months 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 5 months 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 5 months 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?

comment:23 in reply to:  22 ; Changed 5 months ago by acat

Replying to gk:

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?

I updated the bug with a bit more info, do you have any idea of who could we ni? from mozilla?

comment:24 in reply to:  23 Changed 5 months ago by gk

Replying to acat:

Replying to gk:

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?

I updated the bug with a bit more info, do you have any idea of who could we ni? from mozilla?

Without looking closer my strategy would be to ni? the one who originally wrote the code we need to patch and/or ask tjr to help us finding the proper person to ni?

Note: See TracTickets for help on using tickets.