Surprisingly few comments about the actual attack mechanism here. IMO discussion of whether the author's PoC was ethical is interesting but far less important than the question about how to handle the actual vulnerability; this kind of attack could be used for far more damaging things than just recording user behavior. (Such as phishing.)
IMO "get rid of the browser history API" (as the article author recommends) isn't the right solution. The history API is important, as it's the only way to make the back button work as expected in single-page applications, or in multi-page applications that don't trigger a full page reload when you click a link. Rather, I'd suggest the following mitigations:
1. Require a user gesture for `History#pushState` and `History#replaceState`
2. Follow Firefox's example and highlight the most important part of the domain name in the browser UI
I think getting rid of the history API is really the only way to do this since it lets pages escape the browser chrome. No code from a page should affect the behavior of the chrome elements. It's always ends up being used maliciously.
Changing the UI in case of a different domain is genius, would really help in enforcing the principle of least astonishment. However I don't think the up arrow symbol would work since it already has a meaning in traditional file browsers to indicate going up a directory.
I can suggest a back arrow behind a no way sign instead, but perhaps it should be something totally different.
Another possibility - if the referring page is a different domain, overriding back is ineffective (the browser just does a “real” back in these cases).
I don't understand. Are you suggesting that if you arrive at a site from Google, the history API should just not work?
For example, let's say a user arrives at a single-page application from Google, and clicks a link on that page to get more information. The site adds a history entry with pushState, but doesn't reload the entire page. Are you saying that in this case, when the user clicks back they should get sent back to Google instead of to the site's home page? If so, that seems like rather unexpected behavior. And if not, isn't the attack still viable?
To make 4. useful, links with the domain different than the open one should not be allowed to be added to History, otherwise you can bypass it with a different domain.
And without 4. this new limitation could be bypassed with a redirect (from the same domain).
> links with the domain different than the open one should not be allowed to be added to History
This is already the case, and AFAIK it's always been this way.
From [the HTML standard for pushState][1]:
> Compare newURL to document's URL. If any component of these two URL records differ other than the path, query, and fragment components, then throw a "SecurityError" DOMException.
Fair point; popstate allows you to do pretty much anything when the history entry is for the current domain.
That's not really an issue for this particular attack though, which relies on the reverse scenario: the user remaining on the current domain when they expected to navigate back to the third party search engine.
IMO "get rid of the browser history API" (as the article author recommends) isn't the right solution. The history API is important, as it's the only way to make the back button work as expected in single-page applications, or in multi-page applications that don't trigger a full page reload when you click a link. Rather, I'd suggest the following mitigations:
1. Require a user gesture for `History#pushState` and `History#replaceState`
2. Follow Firefox's example and highlight the most important part of the domain name in the browser UI
3. Don't label HTTPS sites as "Secure", as this can be misleading (Chrome's planning to do this starting next month https://blog.chromium.org/2018/05/evolving-chromes-security-... )
4. Give the back button a different icon when it's taking you to a different domain (maybe "Up" instead of "Back"?)
Any other ideas?