Thanks for posting this. I wouldn't have known otherwise of the attempt from the authors of the paper which this demo is based to introduce this vulnerability into Firefox[1]. Really leaves a sour taste in mouth from how irresponsible and unethical this was.
This is a neat approach, but I'm not sure I'd expect it to be used in the wild. ~32 consecutive document redirects every time you want to fingerprint a browser would be slow: twelve (?) redirects on my (~fast) internet takes about ten seconds. On 3g, I could imagine this taking much longer.
You'd also likely need to do this at the (root) page level (i.e., it wouldn't work inside an iframe, since iframes don't have favicons), and it breaks the back button really hard. I'm not sure I can think of a practical situation where this could actually be used for tracking. Maybe if it was done in a popup?
Funny you mention that, one of my friends was on a torrent site the other day and had tiny popup that appeared to keep redirecting. I assumed it was redirecting through multiple pages to generate fake ad impressions, but this is another possibility.
Yeah, the demo page is using a ±800ms timeout on purpose.
I chose the threshold so that even with a bad internet connection, slow browser, etc. the favicon is requested without the redirect being faster than that.
So it is definitely possible to reduce the timeout significantly but it is not useful for demonstration purposes... ~jonas
Potential workaround: redirect a more bearable amount of times (2-3) every time a user clicks a link on your website. An aggressive ad network could also do this across websites.
If the browser supports JS, maybe you can quickly generate uuid based on the same pattern, load the favicon as data url and with onload, check if it's in cache. This would make it significantly faster.
This only applies to browsing where the user's cache is present, yes?
At least in Firefox 85.0.1 Desktop and 85.1.1 Android (when I tested) clearing the cache also nukes the favicons as well.
Also, I get different hashes when I test on demo.supercookie.me after clearing my cache on mobile, and also across Private windows on desktop.
The statement "[...] even in the browser's incognito mode and is not cleared by flushing the cache, closing the browser [...]" is misleading, at least where Firefox[0] is concerned.
Tested on Firefox 85.0 on Linux mint. The id is different across a normal window and a private window.
Also tried using a new profile using `about:profiles` and again the id was different.
It doesn't work in FireFox 85.0 x64 on Windows. I went to the site, did the demo, my number was A5 94 D6 7E 4A DE and when I came back in private mode it was 51 ED 26 D8 66 FC.
I can't tell from your post if you are surprised by this or just pointing it out for others who would prefer to avoid this sort of tracking, but just to be clear, this is by design:
Same on Firefox on linux. I got a fingerprint on one tab, and when that finished, I opened a new tab and ran the demo again - which gave me a new fingerprint ID.
You don't even need to come back with incognito mode. At least for me, just pressing the "try again" button gives me a different ID. (Firefox 85, windows)
This is why we can't have nice things. Though I think I could do without favicons fetches to webserver. Perhaps bruisers should only take them from literal data embedded on the root page.
What's the best way to prevent this for Chrome? Can the F-Cache be disabled entirely? Otherwise, would
a Tampermonkey script or Chrome extension which just GETs /favicon.ico on every page load work?
Some users (including myself) disable favicons, since I don't use favicons. (I disabled it when I set up the computer, far before I heard anything about favicon supercookies.)
In this case, it may be able to figure out that favicons are disabled (if the implementation is written to support that), but not more than that.
Didn't understand what's the purpose of the redirects.
Can't you just track the user by defining a hash to the favicon, for each page, for example, favicon-8h05Gct.ico, by that making the browser download again and again "new" favicon -> and you will gather the data?
If I understand this all correctly, that’s not how this attack works.
You have no way of sending them a unique hash, because if you could, you would have identified them already.
Instead, in this approach each request provides a single bit of information. There’s one part, where you write the hash and the user ends up with a load of fav icons in their cache.
When you want to identify them (read stage) you see which icons they have. The unique collection identifies them. This is done by sending them to different pages, each with a different fav icon.
During this phase you return 404 so do you don’t add more icons to the cache (so you need to be able to split between reading and writing). I didn’t see how they did that in the article, but I guess that’s easy enough by using a sentinel bit at the start (if they didn’t just request that icon, you’ve seen them before).
Didn't understand the flow you explained :(
How the favicon becomes a unique identifier for the user and what more info can i get from that (besides "user 0a465casd entere website")?
When you come across a new user, you need to efficiently identity which hash belongs to that user. Using random hashes would require a linear search. The binary search approach requires redirects to navigate the tree to a unique leaf.
What does "Incognito / Private mode detection" mean?
If I open an incognito window in Chrome (OSX 87.0.4280.141), run the supercookie demo, close all incognito windows, and open/run the demo again, I get a different fingerprint.
Only when I keep an incognito window open does the fingerprint stay the same.
Count yourself lucky then. On older Chrome builds (here 69.0.3497.120 of a Chromebook Pixel which doesn't receive updates anymore), it works just as the author claims.
What I don't get: How does the server decide between read and write mode? Does it first do a read mode redirection and then if the result is "all icons requested" it does a write mode? Or is there one indicative icon that will always be delivered?
So there's indeed an "indicative icon" on the start page that is always delivered. If the browser requests the icon when calling the demo.supercookie.me page, the write mode is invoked, but if the icons is already present in the cache the browser does not send a request and read mode is initiated. ~jonas
Wouldn't the browser do a HEAD first? Seems like you could also use uniquely generated ETAGS as cookies if it does. Which would be more effective with favicons than the general case, given the comments about how browsers cache them.
This idea was indeed my first approach, but favicons on the client side cannot be loaded from the F-Cache via JavaScript, but are ALWAYS requested from the server via get-request, which fortunately thus does not allow fingerprinting. ~jonas
I block favicon requests with a forward proxy. I cannot rely on "modern" browsers to do the right thing, but I can rely on the proxy to do what I tell it to do.
Link to discussion of the paper (55 comments): https://news.ycombinator.com/item?id=25868742
Thanks for posting this. I wouldn't have known otherwise of the attempt from the authors of the paper which this demo is based to introduce this vulnerability into Firefox[1]. Really leaves a sour taste in mouth from how irresponsible and unethical this was.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1618257
Indeed one shouldn't do something like this. I hope they realize their mistake :).
Also thanks for pointing this out, I haven't read that thread that closely, only remembered it being on the hn front page recently.
FTR it seems that Jonas Strehle, author of this Github repo, is not affliated with the authors.
2 replies →
Oh, this `favicon.ico` issues reminds me my old humorous article.[0]
[0] https://appsoft4fm.wordpress.com/2015/06/17/favicon-ico-mone...
This is a neat approach, but I'm not sure I'd expect it to be used in the wild. ~32 consecutive document redirects every time you want to fingerprint a browser would be slow: twelve (?) redirects on my (~fast) internet takes about ten seconds. On 3g, I could imagine this taking much longer.
You'd also likely need to do this at the (root) page level (i.e., it wouldn't work inside an iframe, since iframes don't have favicons), and it breaks the back button really hard. I'm not sure I can think of a practical situation where this could actually be used for tracking. Maybe if it was done in a popup?
> Maybe if it was done in a popup?
Funny you mention that, one of my friends was on a torrent site the other day and had tiny popup that appeared to keep redirecting. I assumed it was redirecting through multiple pages to generate fake ad impressions, but this is another possibility.
The site says that 34 redirects takes about 4 seconds.
The demo page is 1 redirect per second on purpose.
Yeah, the demo page is using a ±800ms timeout on purpose.
I chose the threshold so that even with a bad internet connection, slow browser, etc. the favicon is requested without the redirect being faster than that.
So it is definitely possible to reduce the timeout significantly but it is not useful for demonstration purposes... ~jonas
Potential workaround: redirect a more bearable amount of times (2-3) every time a user clicks a link on your website. An aggressive ad network could also do this across websites.
If the browser supports JS, maybe you can quickly generate uuid based on the same pattern, load the favicon as data url and with onload, check if it's in cache. This would make it significantly faster.
Great idea but favicons used in meta-tags does not support the onload event! I've found a workaround for this but it's only working in chrome. ~jonas
I you wanted to track just a handful of users for nefarious purposes tho...
I think you could also run this on an iframe embedded in a page
What is your response to parent's comment that "it wouldn't work inside an iframe, since iframes don't have favicons"?
1 reply →
This only applies to browsing where the user's cache is present, yes?
At least in Firefox 85.0.1 Desktop and 85.1.1 Android (when I tested) clearing the cache also nukes the favicons as well.
Also, I get different hashes when I test on demo.supercookie.me after clearing my cache on mobile, and also across Private windows on desktop.
The statement "[...] even in the browser's incognito mode and is not cleared by flushing the cache, closing the browser [...]" is misleading, at least where Firefox[0] is concerned.
[0] https://blog.mozilla.org/security/2021/01/26/supercookie-pro...
Tested on Firefox 85.0 on Linux mint. The id is different across a normal window and a private window. Also tried using a new profile using `about:profiles` and again the id was different.
According to the article it looks like they started to fix this between versions 84 and 85.
It's unsurprising that browser manufacturers are patching this.
It doesn't work in FireFox 85.0 x64 on Windows. I went to the site, did the demo, my number was A5 94 D6 7E 4A DE and when I came back in private mode it was 51 ED 26 D8 66 FC.
I can't tell from your post if you are surprised by this or just pointing it out for others who would prefer to avoid this sort of tracking, but just to be clear, this is by design:
https://blog.mozilla.org/security/2021/01/26/supercookie-pro...
The creator of supercookie.me made it sound like all versions of FireFox were vulnerable.
8 replies →
Same on Firefox on linux. I got a fingerprint on one tab, and when that finished, I opened a new tab and ran the demo again - which gave me a new fingerprint ID.
Running privacy badger and ublock origin
Firefox blocks supercookies by default. It's not your addons.
That's it, I'm running Privacy Badger as well!!!
You don't even need to come back with incognito mode. At least for me, just pressing the "try again" button gives me a different ID. (Firefox 85, windows)
Same on Safari in iOS (latest version as of this date).
Same with Samsung Internet on Android
On a Mac, I’m fairly certain you can symlink Safari’s favicon db to /dev/null. That should take care of it. I remember doing this years ago.
This is why we can't have nice things. Though I think I could do without favicons fetches to webserver. Perhaps bruisers should only take them from literal data embedded on the root page.
If only we all used bruisers, they’d really show abusive webservers what for!
What's the best way to prevent this for Chrome? Can the F-Cache be disabled entirely? Otherwise, would a Tampermonkey script or Chrome extension which just GETs /favicon.ico on every page load work?
EDIT: Seems to be preventable with a quick Tampermonkey hack: https://gist.github.com/lukepothier/1b18905039b1ed960efebec3...
On Firefox Focus Android 8.12.0, the demo gets stuck in an infinite loop.
Tracked to incognito, but switching to a different Chrome profile changed the fingerprint, so the F-Cache must be per-profile.
Some users (including myself) disable favicons, since I don't use favicons. (I disabled it when I set up the computer, far before I heard anything about favicon supercookies.)
In this case, it may be able to figure out that favicons are disabled (if the implementation is written to support that), but not more than that.
I’d say “some users” would be 0.00000001% of users
Yeah, I for one have never heard about someone doing this.
2 replies →
Didn't understand what's the purpose of the redirects. Can't you just track the user by defining a hash to the favicon, for each page, for example, favicon-8h05Gct.ico, by that making the browser download again and again "new" favicon -> and you will gather the data?
If I understand this all correctly, that’s not how this attack works.
You have no way of sending them a unique hash, because if you could, you would have identified them already.
Instead, in this approach each request provides a single bit of information. There’s one part, where you write the hash and the user ends up with a load of fav icons in their cache.
When you want to identify them (read stage) you see which icons they have. The unique collection identifies them. This is done by sending them to different pages, each with a different fav icon.
During this phase you return 404 so do you don’t add more icons to the cache (so you need to be able to split between reading and writing). I didn’t see how they did that in the article, but I guess that’s easy enough by using a sentinel bit at the start (if they didn’t just request that icon, you’ve seen them before).
Didn't understand the flow you explained :( How the favicon becomes a unique identifier for the user and what more info can i get from that (besides "user 0a465casd entere website")?
2 replies →
When you come across a new user, you need to efficiently identity which hash belongs to that user. Using random hashes would require a linear search. The binary search approach requires redirects to navigate the tree to a unique leaf.
What does "Incognito / Private mode detection" mean?
If I open an incognito window in Chrome (OSX 87.0.4280.141), run the supercookie demo, close all incognito windows, and open/run the demo again, I get a different fingerprint.
Only when I keep an incognito window open does the fingerprint stay the same.
Cookies seem to behave the same way.
Count yourself lucky then. On older Chrome builds (here 69.0.3497.120 of a Chromebook Pixel which doesn't receive updates anymore), it works just as the author claims.
Wow it tracked into chrome private mode
What I don't get: How does the server decide between read and write mode? Does it first do a read mode redirection and then if the result is "all icons requested" it does a write mode? Or is there one indicative icon that will always be delivered?
So there's indeed an "indicative icon" on the start page that is always delivered. If the browser requests the icon when calling the demo.supercookie.me page, the write mode is invoked, but if the icons is already present in the cache the browser does not send a request and read mode is initiated. ~jonas
Wouldn't the browser do a HEAD first? Seems like you could also use uniquely generated ETAGS as cookies if it does. Which would be more effective with favicons than the general case, given the comments about how browsers cache them.
Browser does NOT do the HEAD request first. Only GET
The browser would presumably send the ETag in an If-None-Match in the GET request though.
3 replies →
Can you read favicons from JavaScript or from the server side? I know you can set them from JS, don’t know about reading.
If so could you use steganography to encode a unique ID into the icon itself, then read it back to retrieve the fingerprint.
This idea was indeed my first approach, but favicons on the client side cannot be loaded from the F-Cache via JavaScript, but are ALWAYS requested from the server via get-request, which fortunately thus does not allow fingerprinting. ~jonas
Makes sense, and I agree that is good behavior! Thanks for clarifying.
Happily, firefox defeats this.
I block favicon requests with a forward proxy. I cannot rely on "modern" browsers to do the right thing, but I can rely on the proxy to do what I tell it to do.
For your age, You are doing amazing! Great work on super cookies.
> About me. I am a twenty year old student from 🇩🇪 Germany
Impressive! Come work with me :) can’t wait to see what you do by the time you’re 30.
Plenty of young people out there in favorable circumstances doing awesome things.
Really? LOL
You may prevent being tracked by blocking .ico request, waiting for the browsers vendors to patch this.
While you're at it block png and gif too
Damn you're right
This might be why Product Hunt's favicon is no longer loading for me. Must be getting blocked.
Doesn't work on Brave for Android - got two different ID's by switching to incognito mode.
Any ways to prevent loading favicons using uBlockOrigin/uMatrix?
hmm, thanks, I think. ....