css @media RFP + window/screen subpixel entropy
Categories
(Core :: CSS Parsing and Computation, defect, P3)
Tracking
()
People
(Reporter: thorin, Unassigned)
References
(Blocks 1 open bug)
Details
Attachments
(1 file, 1 obsolete file)
19.03 KB,
image/png
|
Details |
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0
Steps to reproduce:
In bug 418986 , RFP returns various screen/window metrics as the inner window measurement. This patch also covered [some] css media queries
issue
On devices with a devicePixelRatio !== 1 (results will vary), entropy can be leaked by css and matchmedia queries, when min and max values differ
- screen: @media
min-device-height
(andmin-device-width
I assume) - window: @media
min-height
(andmin-width
I assume) - all the above using a binary method in matchmedia
example
In this example, my phone's devicePixelRatio (dPR) is approx 2.61. I have RFP enabled.
The two matchMedia results show that dPR is not 1, and depending on the actual dPR, the value returned will not be an integer and provides entropy. How much entropy is unknown, but it's not a boolean
The same can happen with pure css, where the result is e.g. 1799 instead of 1800 (so a true/false bit entropy)
possible solutions
When RFP = true, for pure css, and for matchMedia (for the above metrics)
- always round, so at worst it's only a binary entropy
- always return max values for min values. Would this cause breakage?
- always return an integer, rounded up (is that the same as the previous point?)
Reporter | ||
Updated•4 years ago
|
Reporter | ||
Comment 1•4 years ago
|
||
also see bug 1607027 - maybe the answer lies in fixing the underlying devicePixelRatio (which also leaks under css @media and matchMedia)
Updated•4 years ago
|
Reporter | ||
Comment 2•4 years ago
|
||
well, if you're adding blocks, don't forget the other one... bug 1607032 :)
Updated•4 years ago
|
Reporter | ||
Updated•1 year ago
|
Reporter | ||
Updated•1 year ago
|
Reporter | ||
Updated•13 days ago
|
Reporter | ||
Comment 3•13 days ago
|
||
@emilio, when you have time
In fingerprinting we can get measurements via different methods. For example inner window sizes we can use an element, query the document (with no scrollbars), use css, use matchmedia, use an iframe with 100vw + 100vh properties
See https://arkenfox.github.io/TZP/tzp.html#screen, expand the revelant details by clicking [+]
on the right
In the example, which I have used a zoom of 110% to illustrate the issue
- css
- screen uses
min-device-width
+min-device-height
- inner window uses
min-width
+min-height
- screen uses
- matchMedia uses a binary search function and returns the lower bound
- screen between
device-width
+max-device-width
(+ same for height) - inner window between
width
andmax-width
(+ same for height)
- screen between
css
and matchMedia
leak subpixels - and only in screen
+ inner window
, with the value always being lower. Css doesn't show decimal precision, but the fact that it is 1 px less indicates subpixels (so binary). The value can differ based on system scaling, devicePixelRatio, dpi, layout.css.devPixelsPerPx, zoom - and manifests almost everywhere something can be measured.
Solving subpixel entropy is not a zero sum game. In order to make it harder for fingerprinting scripts and adversaries - where we can lie or eliminate or reduce the entropy per metric, we will. e.g. we spoof window.devicePixelRatio, and other various matchMedia and @media queries.
What would be nice is to remove subpixels here. I have never seen the value be anymore than between 0 and 1 - with the values showing decimal precision, always being lower. IANAE on width vs min-width vs max-width etc, so maybe I am missing something here, or android needs special handling. At the very least this would be good for desktop - again, I have never seen the difference being more than 1
My suggestions were, if RFP is enabled
- return a Math.ceil value
- or substitute the queries made for the ones that are always integers
- e.g. when you query for
min-device-width
, return thedevice-width
value - e.g. when you query for
width
, return themax-width
value
- e.g. when you query for
Is this possible, so that way we always return integers
Reporter | ||
Updated•13 days ago
|
Comment 4•12 days ago
|
||
I'm a bit confused, you can measure the effective DPI quite easily with something like border-width: 0.01px
, so I'm a bit confused about how would any of this help?
Returning fractional inner{Width,Height} values breaks websites (see bug 1676843 and related issues), which is why we don't. But those things being consistent is pretty important.
I guess the easiest way to do what you want (I think) is to update this and this to round to the closest AppUnitsPerCSSPixel()
instead of integer boundaries, so that you always end up with an integer number of CSS pixels per dev pixel. But that can be a rather substantial difference from the scale you really want (e.g. that'd force you to use integer zoom factors or so).
Reporter | ||
Comment 5•12 days ago
•
|
||
so I'm a bit confused about how would any of this help?
Yes I have div and border and other PoCs that reveal entropy, right there on TZP :) Solving subpixels isn't a zero-sum game. If we can make scripts have to touch the dom or implement more perf costly measures, then we're in.
IANAE on the moz code base - I don't want to touch everything (or lots of things), just those specific items above - for example we're not actually changing the actual inner size (width
), we're just returning max-width
(when we ask for width
). As for screen, surely forcing an integer there will not beak web content.
Maybe this is too hard to engineer - I was just hoping there was an easy "input" part where the code could swap e.g. width
for min-width
min-device-width
with device-width
(edit: and only in css and matchMedia)
edit: fixup parameters
Reporter | ||
Comment 6•12 days ago
|
||
with the [css and matchMedia] value[s] always being lower
correction: only with css. matchmedia can be higher or lower
Description
•