Tor Browser DPI spoofing omitted window.devicePixelRatio

I suspected that the test for DPI at browserspy.dk was not functioning properly, so I kind of dared people on Twitter to come up with a PoC for using relative element sizing to infer true DPI, beating Tor Browser's DPI-spoofing. 0xPoly reported that the true DPI size can be inferred via such a mechanism, and provided the following example PoC:

page.html:

<div id='testdiv' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>

page.js:

var devicePixelRatio = window.devicePixelRatio || 1;
dpi_x = document.getElementById('testdiv').offsetWidth * devicePixelRatio;
dpi_y = document.getElementById('testdiv').offsetHeight * devicePixelRatio;

alert(dpi_x);

In Tor Browser, even on high-density displays, the DPI is correctly spoofed to 96x96, and the above code does alert('96'). However, if the user changes the zoom level, i.e. via Ctrl-+ or Ctrl--, then the above Javascript will detect a non-96x96 DPI. When I tested (on a machine with a 96x96 DPI display), zooming once led to alert('115.20000457763672'), however that '115.20000457763672' stayed the same if I scaled the browser window size differently and reloaded the page (keeping the zoom at the same level). Peter Todd reported that detecting the zoom level also works on a high-density display.

This may particularly be a problem on huge displays, or any other displays probably viewed from a greater-than-arms-length distance, where the users are constantly zooming in.

Possibly related: #7256 (moved)

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information