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)