[selectors] Solve :visited once and for all
Nobody has claimed this yet.
- Dominant language
- Bikeshed
- Stars
- 4.9k
- Forks
- 816
- PR merge metrics
- PR metrics pending
Description
In https://github.com/w3c/css-houdini-drafts/issues/791 @deian explains a new channel for high-bandwidth leaking of :visited state by observing repaints with the Houdini Paint API. There doesn't appear to be a reasonable way to shut this down under the current regime of partial-censoring of :visited - the current fix for Chrome is to just disallow the paint() function from being used at all on any <a> element or its descendants.
We really need to finally define a sensible model of :visible-state visibility, based on what information would have already leaked to the page via standard, unpluggable channels; then we can finally drop all the silliness around :visited and just treat it as a plain, ordinary pseudo-class that allows all properties to be used in the standard fashion.
-
At minimum, same-origin visitedness is always visible to the page, as the server can track its own cross-links, assuming standard tracking mechanisms exists (cookies, sufficiently high-entropy user identification, etc). So all same-origin links should report :visited.
-
Cross-origin inbound links are always visible to the page if the Referer header was sent in the request.
-
Cross-origin outbound links are always visible to the page if the user visited that link from this origin, as there are a multitude of ways to track outbound links (JS auditing,
<a ping>, link shorteners, etc). -
Any others?
If a link matches one of the conditions above, and is visited, it's allowed to match :visited; otherwise it never matches :visited. So, what's the cost/benefit of each of the conditions above?
1 is easy to apply and non-controversial. It also probably represents at least half of the benefit of :visited styling for the user - they can tell when they've already visited a given page on a site.
But I don't think it's a whole lot more than half - there is a lot of benefit to knowing what links you've visited from a given page, regardless of origin. (Think of clicking thru each of a list of outbound links, such as in a forum post, or in Google search.) So I think 3 is most of the rest of the benefit, but probably the most controversial in terms of theoretical privacy (even if it's nil in practical privacy for the vast majority of users). I think it's reasonable for browsers to nix this condition if the user is blocking script, as that's the primary tracking mechanism.
I think 2 is of relatively minor benefit, but it lies inbetween 1 and 3 in terms of privacy leaking. Some UAs do offer the ability to block Referer, and of course they would then block this visitedness channel, but otherwise it's common and not a big deal. It's just that most cross-origin pages won't have a link back to the page you visited from; the exception is things like weird cross-site web puzzles, or old-school webrings.
Are there any other conditions that would allow us to safely expose :visited state unreservedly?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the linked Houdini Paint API issue and the proposed conditions for exposing :visited state. The issue does not name files or tests; the work is done when the CSS Working Group agrees on a sensible visibility model and its privacy trade-offs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css
- Domain
- frontend, security, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100