It is well-known that styling visited links differently from unvisited links opens the door to attacks that leak the user’s browsing history. Currently, there are brief mentions of preventing these attacks in Selectors 4. Recently, we have seen cross-browser interest and support for strengthening this language, specifically with respect to the proposal to partition :visited links history: https://github.com/explainers-by-googlers/Partitioning-visited-links-history. This was originally proposed in WICG issue #100.
“Since it is possible for style sheet authors to abuse the :link and :visited pseudo-classes to determine which sites a user has visited without the user’s consent, UAs may treat all links as unvisited links or implement other measures to preserve the user’s privacy while rendering visited and unvisited links differently.”
This might become:
“Since it is possible for style sheet authors to abuse the :link and :visited pseudo-classes to determine which sites a user has visited without the user’s consent, UAs must either treat all links as unvisited links or attempt to preserve the user’s privacy while rendering visited and unvisited links differently. Once a user visits a link, UAs should not style that link as :visited across all sites. Rather, UAs should only style a link as :visited if the user has previously visited it from this specific context. Browsers can experiment with the scope of the :visited context based on UX and performance outcomes.”
We can then provide more detail in the Appendix regarding our suggested algorithm for achieving this: triple-key partitioning. On the user’s end, this will mean that the browser styles links as :visited if and only if they have been visited from this top-level site and frame origin before*.
*However, we are currently experimenting with an exception to this rule, which would include the concept of “self links.” For a site foo.com, links displayed within this site that also point to foo.com may be styled as :visited even if they have not been visited from this top-level site and frame origin before (this is because the server already knows that this subpage has been visited). Self links may only be styled in top-level frames or same-origin subframes to prevent cross-site leaks.
Partitioning (including self-links) renders the side-channel attacks previously used to obtain :visited history obsolete, as there is no more global :visited state for sites to leak. Attackers can now only acquire :visited history for links the user clicked on their own site (which is information already available to them). For more details on how partitioning preserves the user’s privacy, please visit the explainer.
While the existing language supports partitioning, it would be nice to take advantage of the recent support for stronger privacy language.
Agenda+ to propose adopting the slightly stricter language in Selectors ("must preserve user privacy"), and adding the informative appendix describing Chrome's triple-keying behavior as a possible way to do so.
It is well-known that styling visited links differently from unvisited links opens the door to attacks that leak the user’s browsing history. Currently, there are brief mentions of preventing these attacks in Selectors 4. Recently, we have seen cross-browser interest and support for strengthening this language, specifically with respect to the proposal to partition :visited links history: https://github.com/explainers-by-googlers/Partitioning-visited-links-history. This was originally proposed in WICG issue #100.
Selectors Level 4 currently states:
This might become:
We can then provide more detail in the Appendix regarding our suggested algorithm for achieving this: triple-key partitioning. On the user’s end, this will mean that the browser styles links as :visited if and only if they have been visited from this top-level site and frame origin before*.
*However, we are currently experimenting with an exception to this rule, which would include the concept of “self links.” For a site foo.com, links displayed within this site that also point to foo.com may be styled as :visited even if they have not been visited from this top-level site and frame origin before (this is because the server already knows that this subpage has been visited). Self links may only be styled in top-level frames or same-origin subframes to prevent cross-site leaks.
Partitioning (including self-links) renders the side-channel attacks previously used to obtain :visited history obsolete, as there is no more global :visited state for sites to leak. Attackers can now only acquire :visited history for links the user clicked on their own site (which is information already available to them). For more details on how partitioning preserves the user’s privacy, please visit the explainer.
While the existing language supports partitioning, it would be nice to take advantage of the recent support for stronger privacy language.