a:visited样式失效问题

在敲入一本书上关于a:visited改变背景图片的css样例时,发现总是不起作用,经过Chrome 30,Firefox 25,IE11验证均不起作用,反复确认没有输入错误,这会不会是一个bug呢?经过搜索,在stackoverflow上发现,这是为了防止通过设置和获取a元素的大部分样式来阻止通过css样式区别来收集用户访问记录的一种安全性措施,原因在这里以下引用原文,懒得看的直接跳过原文看要点。

Privacy isn’t always easy.

We’re close to landing some changes in the Firefox development tree that will fix a privacy leak that browsers have been struggling with for some time. We’re really excited about this fix, we hope other browsers will follow suit. It’s a tough problem to fix, though, so I’d like to describe how we ended up with this approach.

History Sniffing

Visited and Unvisited LinksLinks can look different on web sites based on whether or not you’ve visited the page they reference. You’ve probably seen this before: in some cases, visited links are purple instead of blue. This is just one of the many features web designers use to make the web the best it can be, and for the most part that’s a good thing.

The problem is that appearance can be detected by the page showing you links, cluing the page into which of the presented pages you’ve been to. The result: not only can you see where you’ve been, but so can the web site!

Originally specified as a useful feature for the Web, visited link styling has been part of the web for… well, forever. So this is a pretty old problem, and resurfaces every once in a while to generate more paranoid netizens.

The most obvious fix is to disable different styles for visited versus unvisted links, but this would be employed at the expense of utility: while sites can no longer figure out which links you’ve clicked, neither can you. David Baron has implemented a way to help keep users’ data private while minimizing the effect on the web, and we are deploying it to protect our users. We think this represents the best solution to the problem, and we’ll be delighted if other browsers approach this the same way.

Technical Details.

The biggest threats here are the high-bandwidth techniques, or those that extract lots of information from users’ browsers quickly. These are particularly worrisome since they enable not only very focused attacks, but also the widespread brute-force attacks that are, in general, more useful to a variety of attackers (potentially including fingerprinting).

The JavaScript function getComputedStyle() and its related functions arefast and can be used to guess visitedness at hundreds of thousands of links per minute. To make it harder for web sites to figure out where you’ve been without radically changing the web, we’re approaching the way we style links in three fairly subtle ways:

Change 1: Layout-Based Attacks
First of all, we’re limiting what types of styling can be done to visited links to differentiate them from unvisited links. Visited links can only be different in color: foreground, background, outline, border, SVG stroke and fill colors. All other style changes either leak the visitedness of the link by loading a resource or changing position or size of the styled content in the document, which can be detected and used to identify visited links.

While we are changing what is allowed in CSS, the CSS 2.1 specification takes into consideration how visited links can be abused:

“UAs may therefore treat all links as unvisited links, or implement other measures to preserve the user’s privacy while rendering visited and unvisited links differently.” [CSS 2 Specification]

Change 2: Some Timing Attacks
Next, we are changing some of the guts of our layout engine to provide a fairly uniform flow of execution to minimize differences in layout time for visited and unvisited links. The changes cause all styles to be resolved on all links for both visited and unvisited states, and it is stored; then, when the link is styled, the appropriate set of styles is chosen making the code paths for visited and unvisited links essentially the same length. This should eliminate some of the easy-to-mount timing attacks.

Change 3: Computed Style Attacks
JavaScript is not going to have access to the same style data it used to. When a web page tries to get the computed style of a link (or any of its sub-elements), Firefox will give it unvisited style values.

What does this mean for users?

For the most part, users shouldn’t notice a change in how the web works. A few web sites may look a little different, but visited links will still show up differently colored. A few sites that use more than color to differentiate visited links may look slightly broken at first while they adjust to these changes, but we think it’s the right trade-off to be sure we protect our users’ privacy. This is a troubling and well-understood attack; as much as we hate to break any portion of the web, we need to shut the attack down to the extent we can.

We have to be realistic, though: there are many ways all browsers leak information about you, and fixing CSS history sniffing will not block all of these leaks. But we believe it’s important to stop the scariest, most effective history attacks any way we can since it will be a big win for users’ privacy.

If the remaining attacks worry you, or you can’t wait for us to ship this fix, version 3.5 and newer versions of Firefox already allow you to disable all visited styling (immediately stops this attack) by setting thelayout.css.visited_links_enabled option in about:config to false. While this will plug the history leak, you’ll no longer see any visited styling anywhere.

Enhancing Privacy on the Web.

We want to bridge the gap between our users’ expectations of privacy and what actually happens on the web. Sometimes users have an expectation that we preserve their privacy a certain way, and if we can, we want to live up to it. Privacy isn’t a feature that can simply be added to a browser, though; it often comes at the expense of utility. We think we’ve found a fix that will balance flexibility for web developers while providing a safer experience for our users on the web.

Sid Stamm, Mozilla Security

要点是:

1.防范通过设置样式进行攻击

a元素的link和visited之间只允许foreground, background, outline, border, SVG stroke和fill colors有不同.

2.防范通过计时攻击

修改了渲染引擎,使得输出a:visited和a:link时间相同,避免对a元素生成计时来判断是否已访问的攻击

3.防范通过获取生成的样式进行攻击

getComputedStyle()无论a元素状态只返回a:link样式

总之结果就是相对a元素的visited伪类单独应用背景图片是不可能的了。

经过测试,Chrome 30, Firefox 25, IE11均已经实现了Firefox4首先实现的这个特性。文中作者的呼吁变成了现实。看来在越来越重视隐私的今天,各家对于自家浏览器的安全隐私都十分重视。

最后附一张对比效果图,IE6作为典型进行对比。

对a:visited应用背景图片样式的对比,Chrome 30,Firefox 25,IE11,IE6
对a:visited应用背景图片样式的对比,Chrome 30,Firefox 25,IE11,IE6