Why can’t I set the font size of a visited link?

Visited links show up purple; unvisited links show up blue. This distinction goes back to the beginning of the web. But CSS allows you to customize this visual difference using the :visited pseudo-selector! Say you wanted to make visited links gray and smaller, to indicate to the user that this link is “done”:

a :visited { color : gray ; font-size : 6px ; }

This style is applied on this page, and here’s a sample:

Notice that the visited link appears gray, as expected, but the font size hasn’t changed! This is because changing the font size would be a security vulnerability! If CSS could set the font size differently, I (Jim) could tell whether you’ve visited pornhub.com . But how?

Web pages are able to inspect the rendered elements on the page. The most obvious way is with window.getComputedStyle() . Here are the reported properties of the above visited link, as reported by your browser: .

If getComputedStyle were to report 6px instead of 18px for visited links, I could have this page generate a link to pornhub.com , then test its font size, in order to reveal your browsing history. I could then serve you targeted ads, sell your data, blackmail you, et cetera. This security hole has been plugged by not allowing a:visited to set the font-size .

But notice what getComputedStyle reported for the color of the visited link: rgb(0, 0, 238) , i.e., blue. This is a lie - the link is gray! For the color property, browsers have plugged the security hole in a different way: instead of disallowing the property to be customized, they have getComputedStyle lie about its value.

Why two approaches? Why can’t we have getComputedStyle lie for font-size , too? The reason is that web pages can inspect the rendered elements via more than getComputedStyle . Web pages can check an element’s position in the page, via .pageXOffset or .pageYOffset . Since font-size of the visited link would affect the offset of other elements, the page could indirectly check whether the link is visited. Disabling font-size for a:visited is a brutal, but safer, solution.

There’s a short whitelist of properties that, like color , shouldn’t affect page layout, and so shouldn’t be detectable. They’re all different forms of color. All other CSS properties are banned.

In theory, there is no way that a web page can determine whether a link has been colored differently. One possibility is a timing attack: say, if it takes longer to color something pink compared to blue, the page could measure how long it took to render the element, and compared this to an expected duration.

I just released Vidrio , a free app for macOS and Windows to make your screen-sharing awesomely holographic. Vidrio shows your webcam video on your screen, just like a mirror. Then you just share or record your screen with Zoom, QuickTime, or any other app. Vidrio makes your presentations effortlessly engaging, showing your gestures, gazes, and expressions. #1 on Product Hunt. Available for macOS and Windows. With Vidrio With generic competitor

More by Jim

Tagged #programming, #web, #css, #security. All content copyright James Fisher 2019. This post is not associated with my employer. Found an error? Edit this page.