
CSS mix-blend-mode is bad for your browsing history - kawera
https://lcamtuf.blogspot.com/2016/08/css-mix-blend-mode-is-bad-for-keeping.html
======
overgard
Clever!

Here's one way I can think of to fix it without just taking out the feature or
trying to hide its results: redefine "visited" from being "visited ever, from
anywhere" to "visited from here". For instance, if I visited a wikipedia
article on my own, and it appeared on hacker news, it wouldn't appear as
"visited". However, if I clicked on it from hacker news, next time I load
hacker news the browser would mark it as visited. I think that would keep all
the useful properties of visited, without leaking information.

~~~
derefr
I like that!

My own suggestion would be to make :visited something that renders at the
browser-chrome level (like OS tooltips or IME controls), rather than the
renderer level (like on-page find result highlights or selection-caret link
outlines.) Don't hand the state to the renderer process in the first place;
just stuff it in the renderer-inaccessible part of the DOM (like XHR response
cookies) and then have the browser indicate where on the rendering surface the
visited—or maybe unvisited!—links are, in some floating-control fashion
(perhaps like Firefox's find-in-page scroll-bar notches.)

~~~
dfabulich
Where would chrome like that appear in touch UI? Typically tooltips show on
hover, but touch UI has no hover effect.

~~~
Senji
Doesn't need to be a hover element. It cam be an underline or a translucent
square.

------
vessenes
If you're following along in the code, four classes are defined, l_and,
l_and:visited, l_and_not, l_and_not:visited.

l_and:visited and l_and_not are set to background color white, the others
black.

512 link 'stacks' are created, each one in a td tag, each one for each
possible setting of the 9 sites he checks.

Each of the classes get mix-blend-mode: multiply turned on.

He then looks for a final image with color white -- that's the bitset of your
visited sites, since the multiplies will all give white as the output.

------
callesgg
I think the best solution would be if visited only applied to the local
domain.

Like all the other cross domain policy stuff.

------
bennettfeely
This article would more accurately be named the CSS :visited psuedo-class is
bad for your browser history, not blaming it on the mix-blend-mode property.

The same idea has been done before, except more cleverly with the color
property and captchas:

[https://frantzmiccoli.github.io/visited-captcha-
history/](https://frantzmiccoli.github.io/visited-captcha-history/)

~~~
LukeShu
Did you read the article? It explains how browsers mitigated the :visited
pseudo-class issue, then how he bypassed that mitigation using mix-blend-mode.
As presented, mix-blend-mode absolutely is to blame for being able to exploit
it.

He also explains how this is different than the captcha POF that you linked
because the captcha requires user interaction for _each_ URL tested (something
that wasn't necessary before the browsers mitigated against it). He explains
how to reduce this to a _single_ user interaction, by exploiting mix-blend-
mode.

Yes, :visited is a key part of the exploit, but to say it's just that isn't
accurate.

~~~
ianstormtaylor
I think grandparent's point is that `:visited` is actually the source of the
problem, and that the "fixes" that browsers applied were leaky. Surely this
will continue happening with future additions to CSS.

It seems like a perfect example of leaky abstractions.

~~~
eriknstr
I think the title is very good because I am aware of problems and mitigations
with :visited, so if the title just talked about :visited, I would have
thought to myself, "yup, good thing they fixed that long ago in all browsers",
whereas with the present title, I actually learned about these new
discoveries.

------
Kiro
> This problem was eventually addressed by browser vendors by simply improving
> the accuracy of color quantization when overlaying HTML element

What does this mean?

~~~
_pmf_
> What does this mean?

It means the problem was solved accidentally.

Luckily enough, all problems will be solved for good by rewriting the browser
in Rust, according to my reliable 10x engineer sources.

~~~
Kiro
Thanks but that doesn't answer my question at all. I want to know what
"improving the accuracy of color quantization when overlaying HTML element"
means exactly.

------
ComodoHacker
Tor Browser doesn't seem to add[1] any defenses against history disclosure
attacks.

1\.
[https://www.torproject.org/projects/torbrowser/design/](https://www.torproject.org/projects/torbrowser/design/)

~~~
ashitlerferad
Any Tor Browser user would be clearing their history constantly with the "New
Identity" feature.

------
visarga
This is very bad. If I open a website and it knows which of 100 other
specifically selected sites I visited, I'd be instantly "profiled" for
advertising. Is it possible to block visited link leaks? I'd be willing to
give up visited highlighting altogether.

~~~
pdkl95
In about:config, set this option to false

    
    
        layout.css.visited_links_enabled
    

(if missing, create it as a boolean)

I disabled :visited coloring a long time ago and it hasn't caused any
significant problems. It just took a few weeks to get used to the changed link
colors.

------
joshfraser
You can also get browser history by misusing CSP violation reports.

~~~
captn3m0
It has since been fixed since Chrome 48, it seems. Not sure about other
browsers. The attack is pretty interesting btw: pinning CSP to http-only,
which means that the block can be timed to reveal whether the URL was in
history.

the fix was just dis-allowing CSP to restrict to http.

------
huuu
Does this require a click from the user? Couldn't you set a background image
to make a GET request to the server with the results?

~~~
kevinsimper
It would make it anyway because it does not know that it is not shown.

------
mirimir
What browsing history? For me, it goes when Firefox closes :)

~~~
allendoerfer
You are a strange man. You don't want browsing history and more important: You
close your browser.

~~~
mirimir
Not only that, I use Linux with LUKS, and shutdown whenever I'm not using the
box :)

------
microcolonel
This is why I don't run JavaScript unless I absolutely must. Unfortunately, a
lot of sites leave no option; I find myself choosing to miss out on the
content rather than risk the exposure and bad usability.

Side note: Michał is truly prolific, I get the feeling that his dream is to
have a full system secure against common attackers, which consumers might
actually want to use. He seems to attack every piece of system software in
every way from design flaws to implementation bugs.

~~~
gsnedders
This attack purely relies on CSS. There's no JS involved. (Okay, there is in
the PoC, but only to provide the alert listing what sites you've visited; the
data leakage can be exploited with no JS involved.)

~~~
sim0n
How could you take advantage of the leak without JavaScript?

~~~
paxcoder
If you turn JS off, you'll still see a mole in the position which signifies
your visited subset of tested-for addresses. If you inspect the code, each
position has multiple anchor elements, the last of which has an onclick right
now. All you'd have to do is add a href to it.

~~~
Matt3o12_
How do you send this information back to the browser then? You can't embed it
into forms nor send requests to the server. While this information is always
there (unless you disable CSS), there is no way to extract it (unless you use
JavaScript).

This is why OPs point is still true. Without JavaScript, this information is
worthless.

~~~
paperpunk
The point is that you can use the technique on a legitimate link on the page,
e.g. a log-in button. The browser will then make a request anyway, through
which you can pass the information back to the server. That is what paxcoder
means by saying using a href instead of an onClick. No JavaScript is needed
for this.

