180 comments

[ 3.1 ms ] story [ 251 ms ] thread
This was really accurate to me. It seems they're using a:visited on several domains to create the "red square" effect.
Yes.

And the only reason you have to click the red squares is to let it know which ones are red. If you try to look up the color of a square using GetComputedStyle, it always comes back gray. That was the resolution of privacy Bug 147777† (":visited support allows queries into global history").

https://bugzilla.mozilla.org/show_bug.cgi?id=147777

What about if you make a screen capture from the page and use coordinates to read back the colours and correlate with the URLs? Seems a possibility based on http://stackoverflow.com/questions/9250505/how-to-upload-a-s....
html2canvas constructs its "screenshots" using information from the DOM, so that wouldn't gain you anything but unnecessary complexity.
Ah, OK, and other methods appear to produce blank images so presumably this route is purposefully locked down too. A java app or add-on would do it but they'd be a bit obvious for most users I'd think.
Heh. I clicked a few before I realized what was going on (looking at the status bar shows the link, which somewhat gives it away). You could prevent this by adding mouseover/out and onclick logic that removed the :href on hover and just colored itself red.
but i guess then it won't be red on hover.
But in that case, you can add CSS to make it red on hover.
Reminds me of that hunter2 password thing. http://www.bash.org/?244321

Basically, the website doesn't know which of the squares are red, that depends on your browser state. By clicking the red squares, you're feeding it data.

The interesting observation I made out of this is that navigating there in an incognito window prevents any links from being considered as visited. That's good to know.

I remember reading about the old CSS history hack (an automated variation of the same theme), which worked until FF4 and IE9.

It's quite interesting to see how such a seemingly simple feature (a:visited) can completely override user privacy if not accounted for.

Hm. Do you really need interaction at all?

Can't you just :visited { margin/pos/whatever }, then probe the dom on that or related elems to extract the juice? Or have browser vendors thought of this?

This is a very old attack that has numerous security measures to prevent you from doing that now.
I presumed as much. But if you can covertly jimmy the UI and parse the user's interaction, you can more or less get at the history like that anyway.

I don't see any secure way to handle this besides disallowing :visited styling entirely.

I'm having a hard time following here. What is "covertly jimmying a UI" and how would it allow you to exploit visited styles?
For a less "covert" example than I am sure the OP was thinking, you could have "click the red button to continue" sort of like this page does. :)
Wouldn't that also require a hundred same sized differently colored buttons, just like this site?
You could prompt the user through multiple pages of "questioning" under a similar premise of psychological analysis, or some other manipulation. This would reduce the number of buttons per page.

That's what I think he meant.

Not necessarily. What if the un-visited box was set to display:none? That would leave you with just the visited boxes showing.

Now make it even less obvious: create a false box with the proper :visited color. That's your bottom layer, your fallthrough if the user hasn't visited any of them. Now position all of the :visited boxes as exactly the same size and position over that bottom layer. Now, when the user clicks the button to continue, they're guaranteed to click either your fallthrough ("user has none of my sites") or one of those you are monitoring for.

The end result of all this is a page that says "Click the box to continue."

> Not necessarily. What if the un-visited box was set to display:none?

Then it would remain 'none' for the visited box too. Messing with 'display' is disabled in 'visited' to prevent this class of workarounds.

(comment deleted)
It's surprisingly hard to do. Since the allowed styling does not affect positioning in any way (you used to be able to change the font-weight, but not anymore) and the browser removes all :visited styling for client side html-image libraries such as html2canvas you need to generate a massive amount of clicks from the user or have them targeted only to visited elements such as this page does.
I remember there being a long string of attacks related to hooks of this kind, but as far as I know it is no longer a problem at all.

It's a good example of just how difficult browser security is.

The page itself can't tell what color the squares(links) are rendered as to the user. That's what the clicking is for. Mwaahaha...
(comment deleted)
(comment deleted)
I just read the source code, uses caches.
Obvious question - how was the list of URLs compiled? Some are really specific like YouTube channels. On the other hand there are only 15 categories and there are probably a lot of people that would not get a single match or only something very generic like Wikipedia.
The coolest way would be cold, hard natural selection from Alexa top sites, possibly with weighting placed to relevant sites at the introduction of the dataset. Perhaps I will fork.
Your interests are: Google, Facebook, Youtube, Yahoo
Yeah - it might be even better to subtract the most common sites, so the results are more peculiar to you.
Creator here. The links were gathered by searching feedlys feed suggestions for different topics.
fivethirtyeight.com appears about a dozen times for me?
Links appear multiple times if they are relevant to multiple interests. Clicks are only counted once.
This just solved a huge problem I've been struggling with. This is beautiful - I don't actually want to know the information I've been trying to access, but it will make the experience better for the user. I now realize I don't HAVE to know - the browser knows, and that's all that matters. I just have to teach the browser what to do.
It was eerily accurate on me.

1. science 2. technology 3. programming

They could do the same game, but hard-code the results, and be right for 95% of the audience here :)
Actually, they don't seem to diverge much. I've tried randomly clicking on grey squares on different areas and it always gave me similar results (programming, gaming, technology, engineering).
I actually was going to come to the comments, assuming they had done that before remembering that I was supposed to view the source.
Hmm, I was: 1. technology 2. programming 3. history 4. politics 5. design 6. architecture

And it was dead-right.

same for me, though I barely read anything on history or politics
guess I sure do love them movies from torrents.

1. technology

2. movies

3. books

4. programming

5. science

6. politics

7. gaming

Pretty inaccurate for me. It game minimum value to books and writing, and i love them both. I just dont open enough links about them (i read the books! Not their sites!)
same with me, my first reaction is

WHAT KIND OF SORCERY IS THIS!?

1.Technology 2.Gaming 3.Programming

Did you ever heard of cold reading?
hey thanks, i just googled it.

I knew something about it (like reading expression or something, from watching 'the mentalist'), but i did not know what it was called.

but CMIIW the technique used in the linked app is categorized as 'hot reading' right? because it somewhat gather information from our "browsing history". Somewhat same technique used by google for user 'profiling' maybe?

just a little bit of assumption.

The hot reading is researching information on you directly which is less relevant in this case as you don't leave implicit traces of "I love reading Konan Doyle" in your researchable browser history. You may have visited some Konan Doyle sites but you can still do it for other reasons than actually liking his books so any such attempt will include a lot of guesswork.
No, it's exactly cold reading, because it tries everything and encourages and watches your reaction (with javascript) to determine which things it was throwing against the wall were relevant to you. It's an ePsychic™:)
(comment deleted)
Here's the same exploit disguised as a game, to make it less obvious that it's tricking the user into interacting with it: http://lcamtuf.coredump.cx/yahh/

Documentation of the game proof-of-concept: http://lcamtuf.blogspot.com/2013/05/some-harmless-old-fashio...

That's really good, and a very informative forum post!
Cool. That is a neat trick/exploit never heard of it before.

Thx. for the links.

My first idea was clickjacking and social networks, but that probably is impossible.
(comment deleted)
If you open the console and run this script, it'll click every single square, giving a list of the most common types of sites in the array being used:

     for(i=0;i<$$('a').length;i++) {
       $$('a')[i].click()
     }
I had to change it to start at i=1 to avoid clicking on the link to github and leaving the page
Ah, that makes sense, I wrote and ran the script before he open sourced it.
Doesn't work for me because I disabled :visited last time this sort of thing got discussed. :V
No red squares here. Am I doing it wrong?
You likely have layout.css.visited_links_enabled (or the equivalent boolean on your browser) set to false.
I don't have any either. I think it's because I've turned off internet history on Firefox.
Yep. I took me a few minutes to figure out why it wasn't working for me...
Haha, should have been pr0n sites :P
Was on incognito and wondering why I didn't see any red squares...
That is, I am guessing, because there aren't any re-marketing cookies,history and other markers when you open the page in incognito
No, it was because incognito tabs don't have access to browser history.

This web-app's functionality is based entirely on browser history and has nothing to do with 're-marketing cookies' or other 'markers'.

Not to mention that the parent commenter clearly understood this fact.

This is quite clever. By the way now I've got a nice list of blogs/websites that I should probably read for various topics.
I was also thinking of using it as a bookmarks site. :)
Couldn't one simply make a display:none on normal links and display:block on :visited, then stack them all on top each other with position:absolute and catch mouse events from each element via JS?
Browsers have a very limited set of properties that they allow in :visited rules, and display isn't one of them.
(comment deleted)