A few years ago window.getComputedStyle
and the like where adjusted to return the default color of links, instead of the actual color on screen.
Security and privacy were the driving factors behind that decision: by styling :visited
links with a different color than their non-visited counterparts, a hacker could easily determine which sites a user has visited by simply checking the color of each link.
// @ref https://dbaron.org/mozilla/visited-privacy
var links = document.links;
for (var i = 0; i < links.length; ++i) {
var link = links[i];
if (getComputedStyle(link, "").color == "rgb(0, 0, 128)") {
// we know link.href has not been visited
} else {
// we know link.href has been visited
}
}
With that hole now plugged for quite some time, Lukasz Olejnik turned towards the Ambient Light Sensor API to perform a likewise hack:
Since a website can apply different styles to visited and unvisited links, but cannot detect how the links are displayed to the user, we use the sensor to identify its true color:
- Set link styles: visited (white), unvisited (black).
- Calibrate: display a white background, then follow with a black background to identify the light levels in the user’s environment; this is also possible, but more difficult, if sensor readings fluctuate significantly.
- Iterate through a list of links, one by one, displaying each of them in turn as a large rectangle which fills the entire screen. Visited links will show up as white, unvisited as black.
- Log the light levels in response to displaying each link, identifying its color. Since we calibrated the screen in step #2, we know which color each reading represents.
At the end the attacker obtains a list of links for which the screen was white and knows that the user had previously visited the given pages.
Using the same technique it's also possible read out QR codes.
Stealing sensitive browser data with the W3C Ambient Light Sensor API →
Leave a comment