Workarounds for :visited CSS History reconnaissance

It is still possible. However, it is much harder to do unobtrusively now. See the following research paper for details of how to do it:

  • I Still Know What You Visited Last Summer: Leaking browsing history via user interaction and side channel attacks, Zack Weinberg, Eric Chen, Pavithra Ramesh Jayaraman, and Collin Jackson, IEEE Security and Privacy Symposium 2011.

Please do not use this to spy on visitors to your web site without their consent. That has the potential to be a bad business move.

We've been through this before. The last time some web sites tried using CSS history sniffing, they eventually got caught. The fact that they were using history sniffing got into the news, and caught the attention of the FTC and many others. Lawsuits were filed, and investigations were opened. So I think we have solid evidence that if you history-sniff your visitors, you are asking for trouble. For more information on this, see the following sources:

  • NAI To Probe Epic Marketplace's 'History-Sniffing' Techniques.

  • Suit to Snuff Out 'History Sniffing' Takes Aim at Tracking Web Users. Note the quote from the FTC official. It's not good when the FTC is willing to make a public statement expressing concerns over your business practices.

  • The FTC Promises an End to History Sniffing (Microsoft, Take Note).

  • Browser History Sniffing in the News. Excerpt: "Clearly, companies know it’s a bad practice to sniff browser history. In fact, it’s probably illegal too."

  • History Sniffing

  • The research paper that kicked off all of this: An Empirical Study of Privacy-Violating Information Flows in JavaScript Web Applications, Dongseok Jang, Ranjit Jhala, Sorin Lerner, and Hovav Shacham, ACM CCS 2010.


It's quite possible. The trick they've used to prevent this attack involves disabling CSS on the :visited selector. However, that doesn't stop the selector from still being there!

You can use JavaScript to iterate through a set of links, checking for the :visited selector on each. It's possible to do the check using cssRules, which should tell you which rules are being applied to a DOM element. Once you've found the visited ones, you can do an Ajax post back onto the site to store the results. There's a proof of concept of this trick, though there's no guarantee of it being correct and functional across all browsers.