Open Bug 1672093 Opened 4 years ago Updated 12 days ago

css @media RFP + window/screen subpixel entropy

Categories

(Core :: CSS Parsing and Computation, defect, P3)

Firefox 83
defect

Tracking

()

REOPENED

People

(Reporter: thorin, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file, 1 obsolete file)

Attached image example (obsolete) —

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 (and min-device-width I assume)
  • window: @media min-height (and min-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?)
Component: Untriaged → CSS Parsing and Computation
Product: Firefox → Core

also see bug 1607027 - maybe the answer lies in fixing the underlying devicePixelRatio (which also leaks under css @media and matchMedia)

well, if you're adding blocks, don't forget the other one... bug 1607032 :)

Severity: -- → S3
Priority: -- → P3
Status: UNCONFIRMED → RESOLVED
Closed: 1 year ago
Resolution: --- → INVALID
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: INVALID → ---
Attachment #9182527 - Attachment is obsolete: true
Attached image example.png

@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
  • 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 and max-width (+ same for height)

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 the device-width value
    • e.g. when you query for width, return the max-width value

Is this possible, so that way we always return integers

Flags: needinfo?(emilio)
Summary: css @media RFP + window/screen leaks → css @media RFP + window/screen subpixel entropy

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).

Flags: needinfo?(emilio)

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

with the [css and matchMedia] value[s] always being lower

correction: only with css. matchmedia can be higher or lower

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: