#896: Partitioning :visited links history

Visit on Github.

Opened Sep 12, 2023

こんにちは TAG-さん!

I'm requesting a TAG review of “Partitioning :visited links history.”

The goal of this feature is to eliminate user browsing history leaks by styling anchor elements as :visited if and only if they have been clicked from this top-level site and frame origin before. On the browser-side, this means that the data structure storing the :visited links would be partitioned via "triple-keying", or by storing the following for each visited link: <link URL, top-level site, frame origin>. By only styling links that have been clicked on this site and frame before, the many side-channel attacks that have been developed to obtain :visited links styling information would become obsolete, as they would no longer provide sites with new information about users.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • The group where the incubation/design work on this is being done (or is intended to be done in the future): WebAppSec WG
  • The group where standardization of this work is intended to be done: most likely either WebAppSec or CSSWG
  • Existing major pieces of multi-stakeholder review or discussion of this design: N/A
  • Major unresolved issues with or opposition to this design: N/A
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as: 💬 leave review feedback as a comment in this issue and @-notify: kyraseevers, arturjanc, miketaylr


Security and Privacy self-review

(1) What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary?

This feature does not expose new information to websites or other parties. It aims to restrict the information exposed by :visited links. The difference between unpartitioned and partitioned :visited links, is that unpartitioned :visited links exposes global user-browsing history state, whereas, partitioned :visited links only exposes what links have been visited from this site before (information that is already known to sites via other methods).

(2) Do features in your specification expose the minimum amount of information necessary to enable their intended uses?

Yes, no new information is exposed.

(3) How do the features in your specification deal with personal information, personally-identifiable information (PII), or information derived from them?

This feature does not deal with personal information, PII, or any information derived from them.

(4) How do the features in your specification deal with sensitive information?

It does not handle sensitive information.

(5) Do the features in your specification introduce new state for an origin that persists across browsing sessions?

No, there isn’t any new state introduced.

(6) Do the features in your specification expose information about the underlying platform to origins?

No, this feature does not expose information about the underlying platform.

(7) Does this specification allow an origin to send data to the underlying platform?

Yes - the link URLs are passed to the platform, however, this is already done by the current :visited links implementation.

(8) Do features in this specification enable access to device sensors?

No, there is no access to device sensors.

(9) Do features in this specification enable new script execution/loading mechanisms?

No, there aren’t any new script execution/loading mechanisms.

(10) Do features in this specification allow an origin to access other devices?

No, this feature does not allow an origin access to other devices.

(11) Do features in this specification allow an origin some measure of control over a user agent’s native UI?

Yes, but no more than the existing :visited link styling capabilities.

(12) What temporary identifiers do the features in this specification create or expose to the web?

None - no new identifiers are created or exposed.

(13) How does this specification distinguish between behavior in first-party and third-party contexts?

First and third parties BOTH must abide by triple-key partitioning. However, there are some edge cases where a first-party embed may display a site not previously visited in that frame (i.e. when a site embeds a iframe containing itself and the user has clicked on a link on this site in a previous visit, the link in both the top-level frame AND the iframe will be styled as visited.)

(14) How do the features in this specification work in the context of a browser’s Private Browsing or Incognito mode?

In private browsing/incognito mode, :visited links are not styled at all.

(15) Does this specification have both "Security Considerations" and "Privacy Considerations" sections?

Selectors 4 has some existing language for both privacy and security considerations - https://www.w3.org/TR/selectors-4/#priv-sec

(16) Do features in your specification enable origins to downgrade default security protections?

No, all origins are partitioned equally.

(17) How does your feature handle non-"fully active" documents?

History is only written to the :visited links database and hashtable once navigation is complete. We are not making any alterations to the timing of when the renderer requests the :visited status of a given link during CSS parsing.

(18) What should this questionnaire have asked? Nothing to add.

Discussions

2023-11-13

Minutes

Amy: seems good, what's the catch?

Peter: I know there are other mitigations to using visited links as fingerprinting. i wonder if this is necessary if those other mitigations are used. this has impact to the user. not sure this is a benefit to the user.

Amy: it's a trade-off... but there is a citation that we don't understand how people feel about links being styled differently.

Peter: I rely on it.

Lea: we've learned not to rely on it but when it is there it can be quite useful.

Lea: this partitions history based on origin... if we wanted to implement this using JS we could do it... If you can have the union of these 2 then there are few visited links tyou would miss having...

Peter: i remember years ago David Baron had a proposal letting the style of visited links happen but relying on JS...

Lea: very restricted styling that can be done - only colors really... The point of this proposal is that it's a normal pseudoclass...

... tbc ...

2023-12-11

Minutes

Amy: we definitely discussed this... can't find minutes

Peter: i remember being concerned about : don't we already do this? but it looks like they are taking that into account and going beyond the protections we have...

Amy: was Lea's concern that this would make visited links useless to end users?

Peter: concerns about ... most visited links would not show up as visited.. Triple keying - target, domain and top level domain...

Amy: my perspective is that's probably a reasonable trade-off for not leaking your history... but don't have a good sense of how useful visited links state is for most other people

Peter: personally - search results - visited links are useful - that would not break. Similar a wikipedia site - that would not break. It does break if it's cross-site. If I visit a site where I've never clicked on a link

Dan: Say you visit a link on a social media site to an article in a blog.

Peter: and then you visit another social media site has a link to the same article - it would not show as visited. Users will lose some utility and some may be confused but it won't be the most common cases where we expect visited links to work.

Dan: what do other browsers think of this? No signals. We could say it looks good, we understand the tradeoffs, what feedback is there from other browsers?

Peter: agree we should ask for feedback from other browsers. Not sure we should say it looks good yet, some concerns about user expectations

Peter to leave feedback

2023-12-18

Minutes

No signals from other browsers, so marking 'multi-stakeholder?' We should probably punt/close and ask them to re-open this one, wait for data from experimentation.