Hacker News new | past | comments | ask | show | jobs | submit login
Retrieving your browsing history through a CAPTCHA (2022) (varun.ch)
167 points by miki123211 on July 31, 2023 | hide | past | favorite | 59 comments



I saw a variation of this idea once with a space game. IIRC you control a ship and asteroids attack you. You shoot the asteroids by clicking on them.

The first trick: the asteroids are actually (in)visible depending on whether you had visited a specific website, same as here. If you clicked on an asteroid that's because you could see it, and now you've revealed that you've visited that website before.

Second trick: these asteroids don't actually hit you - they pass close by (close enough that you want to shoot them) but they don't actually aim at you (to keep you playing as long as possible).


> but they don't actually aim at you (to keep you playing as long as possible).

Sounds like they can't have them hurt you since the game doesn't know which asteroids are "real" until you've destroyed them.


Just like this site, you can put some “honeypot” ones that ARE real, and those can be aimed directly at the player, but also don’t trigger any sort of detection.


Not an asteroid game, but similar idea:

https://lcamtuf.coredump.cx/whack/

See also "History theft with CSS Boolean algebra":

https://lcamtuf.coredump.cx/css_calc/


Happy to see neither one works on Safari. One says "no sites visited" and the other "both sites visited" even in incognito.


Reveal it to whom? Sounds like the game already knows which websites you’ve visited without you clicking on them.


Presumably implemented in a browser using CSS :visited the state of which is inaccessible to web programs to protect user privacy. Toggle visibility of the asteroids in CSS and let the user unwittingly disclose which websites they've visited.


so, the asteroids are dumb as rocks?


Chromium is currently trying to partition-visited links to prevent this type of history leakage - see: https://groups.google.com/a/chromium.org/g/blink-dev/c/h7Ahp...


In Firefox it’s possible to disable behavior of visited links, thus mitigating this. Go to `about:config` and set `layout.css.visited_links_enabled` to true.

If you do this, beware this from the PoC when testing:

> Additionally, I included some fake squares to catch if visitors are trying to spoof their results.


> set `layout.css.visited_links_enabled` to true.

set to false you mean, surely?


Yes of course, my mistake. Unfortunately too late to edit.


Wait... if a random site can apply a style to a link to discern whether it's visited or not, why bother having the user click on them? Just render them somewhere outside the visual viewport and check what style gets applied to them? Or do browsers have countermeasures against this?

Sorry if this sounds kind of ignorant, but I do primarily backend stuff lol :)


The JS can't directly compute whether you have or haven't visited the link based on what it looks like. They actually used to (like 15+ years ago) but browser makers patched that REAL fast after some toy projects were able to reveal OUTRAGEOUS amounts of personal info just by getting someone to click a link.

Instead they have to have you the user do something to indicate which ones you can see and which ones you can't. That's why you HAVE to click on the squares. And if you click on white squares, it'll (wrongly) think you've visited sites you haven't. If you click on NONE of the squares, it'll think you haven't visited any of them, since it won't have any way to double check the info.

So that's why they can't "just render it outside the viewport." For sources, see the other comments by folks with good info.


> If you click on NONE of the squares, it'll think you haven't visited any of them, since it won't have any way to double check the info.

It's cleverer than that. There are two positive controls (squares that are always black) and one negative control (always white). If you don't click both positive controls, or if you click the negative control, the page will tell you that you've failed the CAPTCHA.


Article mentions https://stackoverflow.com/a/5396422 as a countermeasure to this


Well, that's what I get for not clicking through on that link ;) Thanks.


The article mentions this, you're limited to what you can set / get on visited link CSS.


Has anyone seen this kind of attack in the wild or are we stuck with increasingly far-fetched blog post examples of someone finding out I've been to google.com?


like more than 15 years ago there was a site that gave you a link you could share with someone and see what they had visited when they clicked.

their database was huge and it went from a funny gotcha to awkward really fast


Yeah that and similar are why a bunch of css properties don’t report their actual computed style to JS


The Asahi Linux website uses it to harass Hacker News submitters: https://news.ycombinator.com/item?id=36231248


That's using the referrer header to detect if you clicked a link to their site from this domain. Totally different box of frogs altogether.

JWZ uses the same trick, and redirects to an image of a hairy ball in an eggcup.

Unless they're also doing some CSS stuff I haven't read about.

Edit: clicked through a bit more. a red banner got added to their site using something like this.


> That's using the referrer header to detect if you clicked a link to their site from this domain. Totally different box of frogs altogether.

No, that's what they used to do until HN got updated to put rel="noreferrer" on the links specifically to stop that.

> Unless they're also doing some CSS stuff I haven't read about.

That's exactly what they're doing now. They have white-on-white text at the top of every page that turns red (i.e., becomes visible) if you've ever visited the HN submit page.


Holy moly, the hypocrisy is astounding. Why would anyone ever trust software written by a person so lacking in integrity?


It’s high time browsers stop supporting :visited on cross-domain links by default.

No need to remove the feature completely, just not applying :visited on cross-domain links would fix privacy leak, while keeping most legit uses of :visited working fine.


I really hope not. If I'm repeatedly googling a related set of queries, knowing which pages I've already looked at is hugely helpful.


It's been years that Google search result pages do not link directly to content, but goes through a google.com "redirect" url, so this use case could still work.


sounds like that's an obvious loophole to get around the protection then if they did allow same domain only

edit: no I'm wrong, it's early here and I've not had coffee


its also useful on hacker news to see what i already visited especially when headlines get changed.


Something similar to browser fingerprints?


Related:

Retrieving your browsing history through a CAPTCHA - https://news.ycombinator.com/item?id=30569396 - March 2022 (56 comments)


Apparently that's not the case, but I'd expect links to be marked as visited only if I clicked them from that page.


Chrome is proposing switching to that behavior: https://chromestatus.com/feature/5101991698628608


> This also can't be patched unless browsers stop allowing websites to style links

This sounds sensible. Color is perhaps the only thing that browsers should be able to control.


Couldn't even that be abused? A link that's just a square character styled either black or white could look really similar to the demo.


Agreed. Browsers should stop allowing a lot of things. In my opinion, they give way too much freedom to websites. That freedom can and should be taken away if it's abused.


Why can't we have situation where the CSS tells the browser what colours things should be etc, the browser does it, but the site cannot retrieve information about what colour the links are?

There's all kinds of things browsers do that no amount of coding will help me access because there's no public API for it. Why should this be any different?


This is the whole point of the link, even if the browser doesn't returns the correct information, there's still some ways to leak it through user action.


This is... great... A part of me loves it... but I agree with the author, there's significant possibility for data gathering if someone were able to find a way to convince people to go through these regularly -- boxes probably would raise a question mark to visitors (but worked perfectly fine as a POC).


Private browsing does not prevent data to leak, but only prevents local storage. Something like that is in the typical disclaimer.

Turns out that it does prevent leaking data in this case. No local data, no history, no boxes to click, no data leaked.


I've visited Twitter, but it got that one wrong (said I did not visit).


:visited is per URL, and the PoC only checks the Twitter logged-out home page, so it's entirely possible that you haven't visited that recently enough to appear in your browser history.


This seems to me like it could be fully automated. What prevents me from rendering this into a canvas and then accessing the pixel colors from JavaScript?


I briefly touched on that in the explanation. The getComputedStyle function lies about the styling of links. I haven't looked into canvas based approaches but they're probably similar.

There are timing attacks that work automatically though. https://ndev.tk/visted/ works on Chrome.


Fortunately, I visit random websites in a disposable VM on Qubes OS, which does not have any browsing history.


I didn't know this actually existed. I will have a little dig at it.


Moral of the storey. Write your own OS and code if you want privacy.


How so? Surely one wouldn't think to mitigate this kind of attack unless you'd already seen it.


I dont need to have already seen it.


is user input needed or can it be done without it?


needed


so I just spent the last hour tinkering with it, I think there is definetly room for some timing attack, at least on firefox, there is a pattern


Here's a timing attack that doesn't need any user interaction: https://ndev.tk/visted/


Only seems to work in Chrome (not Safari or Firefox).


awesome thanks!


That's cute! Good idea.


Genius


Nice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: