For more information about this, have a look at David Baron’s post, the bug and the post on the security blog.
For many years the CSS :visited selector has been a vector for querying a user’s history. It’s not particularly dangerous by itself, but when it’s combined with <a href="https://developer.mozilla.org/en/DOM/window.getComputedStyle">getComputedStyle()</a>
in JavaScript it means that someone can walk through your history and figure out where you’ve been. And quickly – some tests show the ability to test 210,000 URLs per minute. At that rate, it’s possible to brute force a lot of your history or at least establish your identity through fingerprinting. Given that browsers often keep history for a long time it can reveal quite a bit about where you’ve been on the web.
At Mozilla we’re serious about protecting people’s privacy, so we’re going to fix this problem for our users. To do so we’re making changes to how :visited works in Firefox. We’re not sure what release this will be part of yet and the fixes are still making their way through code review, but we wanted to give a heads up to people as soon as we understood how we wanted to approach fixing this.
These changes will have some impact on web sites and developers, so you should be aware of them. At a high level here’s what’s changing:
getComputedStyle
(and similar functions likequerySelector
) will lie. They will always return values as if a user has never visited a site.- You will still be able to visually style visited links, but you’re severely limited in what you can use. We’re limiting the CSS properties that can be used to style visited links to
<a href="https://developer.mozilla.org/en/CSS/color">color</a>
,<a href="https://developer.mozilla.org/en/CSS/background-color">background-color</a>
,<a href="https://developer.mozilla.org/en/CSS/border-top-color">border-*-color</a>
, and<a href="https://developer.mozilla.org/en/CSS/outline-color">outline-color</a>
and the color parts of the<a href="https://developer.mozilla.org/en/SVG/Tutorial/Fill_Stroke_and_Gradients">fill</a>
and<a href="https://developer.mozilla.org/en/SVG/Tutorial/Fill_Stroke_and_Gradients">stroke</a>
properties. For any other parts of the style for visited links, the style for unvisited links is used instead. In addition, for the list of properties you can change above, you won’t be able to set rgba() or hsla() colors or<a href="http://www.w3.org/TR/css3-color/#transparent">transparent</a>
on them.
These are pretty obvious cases that are used widely. There are a couple of subtle changes to how selectors work as well:
- If you use a sibling selector (combinator) like
:visited + span
then thespan
will be styled as if the link were unvisited. - If you’re using nested link elements (rare) and the element being matched is different than the link whose presence in history is being tested, then the element will be drawn as if the link were unvisited as well.
These last two are somewhat confusing, and we’ll have examples of them up in a separate post.
The impact on web developers here should be minimal, and that’s part of our intent. But there are a couple of areas that will likely require changes to sites:
- If you’re using background images to style links and indicate if they are visited, that will no longer work.
- We won’t support CSS Transitions that related to visitedness. There isn’t that much CSS Transition content on the web, so this is unlikely to affect very many people, but it’s still worth noting as another vector we won’t support.
We’d like to hear more about how you’re using CSS :visited and what the impact will be on your site. If you see something that’s going to cause something to break, we’d like to at least get it documented. Please leave a comment here with more information so others can see it as well.
176 comments