Vulnerability allows cross-browser tracking in Chrome, Firefox, Safari, and Tor
fingerprintjs.com
fingerprintjs.com
It's clever but somewhat obvious (in both a to-the-user-that-its-happening and a "well of course it's possible" sense).
So it's cute, but not practical, and I won't lose sleep over it. I'll probably be more inconvenienced by the mitigations that will surely result that make it that much more painful to actually launch a URL scheme, sadly.
I've actually never checked the "Always open Slack for slack:// links" or similar checkboxes, precisely out of predicting shenanigans like this would happen eventually :)
I wouldn't be too offended if browsers changed the way they handle schemes: always open a "how would you like to handle this link" dialog for any protocol (even if unhandled - like how Windows shows the "how would you like to open this file" dialog), to disguise whether the protocol is handled or not. Not sure I have the answer for user convenience though if someone is used to things automatically opening. That's the "inconvenience" aspect of any potential mitigation, we probably have to get rid of that "remember this choice" checkbox (well, my point is that "have to" is debatable here).
Browser devs definitely still need to patch this vulnerability by making it an instant-return no-feedback prompt to open an application.
As an aside, It's actually surprising the built-in popup blocker let so many popups come from just one user action - I would have thought the heuristic was 1 click = 1 allowed popup before Firefox started denying them.
I think a fix could be: always show a select-program prompt even for unknown schemes (perhaps with a built-in link to the add-ons store a la Windows to find a program to open the "file" ;) ), never fail to a different page context than a successful launch would go to, and make the don't-ask-again checkbox domain specific to prevent random domains doing drive-by automatic launch detection. That seems to solve it without being too disruptive to existing convenience.
As for what normal users want, I would presume most of them would want to be safer on the web.
On the other hand, I guess they could automatically measure the window size in the popups and use this to detect tiling window managers, which gives them another (albeit noisy) bit for fingerprinting...
The accuracy can be low because of:
- Custom browser settings or flags - The demo was designed for the default setup, but that doesn’t mean your custom setup is not vulnerable.
- Poorly performant hardware (including virtual machines) - Some timings are just hardcoded and were tested on the MacBook hardware.
- Fullscreen mode - The demo will work faster and more accurate if the browser is not in a fullscreen mode
- Slow internet connection
- Gestures during the process
Also, we haven’t looked into Opera yet, but we may if you ask to do it.
For the technical questions or bug reports consider using Github Issues
It still may not work for your browser with a custom configuration. Also, it is better not to make any gestures during the process.
https://github.com/fingerprintjs/external-protocol-flooding/...
https://609d9f4d79c4f6000700782c--boring-visvesvaraya-dbefd4...
It didn't work between firefox and chromium on my linux desktop, even trying the chromium branch. But my linux desktop already puts me into a pretty small bucket of users to begin with, so someone who's doing this may not see any joy in trying to fix that.
Linux is tricky. Mostly because Chrome opens applications through `xdg-open`. Custom configuration on Firefox may also affect the result.
EDIT: the "special branch" also didn't work
Wonder is it possible to replace the popup by an iframe?
Good to know who the offenders are, Spotify and Skype. Everything else I uninstalled was actually uninstalled.
Makes me wonder if Windows is somehow pre-installing custom scheme handlers for these, whether you have them or not. As far as I know, Skype comes with Windows, so there is no way to test a fresh installation that never had it at all, but Spotify? Is there anyone using a completely clean fresh Windows installation that can test if this demo thinks it is installed even though it isn't?
When I did it in Safari it actually caused Apple Music to open. When I did it in Chrome it popped up a small square window where I could see it doing it's thing.
Firefox was the only one where it was silent.
But still, that's an interesting hack. Very clever.
Interesting. In my case I saw the little pop up window in all three browsers. Otherwise same results though.
The Epic browser one was interesting. That browser comes with a built in proxy for routing connections through other countries. I use it to get around geolocked content and sometimes for a tiny sense of anonymity. But seeing this able to identify it with same identifier as Brave and Firefox was a bit more troubling. But I guess that comes with the territory of all these browsers using the same Chromium engine.
I'm a bit confused about why so many applications have bothered to create custom protocol handlers. I can see the benefit for something like Spotify, you click a link in your browser and it takes you to the song you want in the Spotify application. But is the NordVPN application really so complex that they can't just say, "hey, open Nord and click this"? Just seems like an unnecessary UX decision. Unless there's something I'm not seeing?
If it’s not going to work, I’d strongly prefer to not make the phone number a link—and perhaps even to present a different flow to the user (e.g. provide a form or mark an email address as the primary option). But if it is going to work, I definitely want it to be a link. It’s common to just guess from the user agent string or screen size whether it’s a mobile device, but that’s extremely flawed too—some tablets will and some won’t be able to dial, and even desktop platforms may well have some VoIP app.
Fingerprinting and usability are so often so significantly at odds. :-(
Edit: It looks like an OS setting. In Windows the URI schemes are configured in the registry: https://stackoverflow.com/questions/80650/how-do-i-register-... Anyone know if there is an easy way to list all the URI schemes?
Edit2: After thinking about this more, I'm afraid that removing URI schemes from the registry may break those programs. I'd much rather have a browser level setting that will only open external http:/https: resources and other URI schemes that are configured from the browser like mailto:.
"This policy setting lets you control whether Windows Store apps can open URIs using the default desktop app for a URI scheme. Because desktop apps run at a higher integrity level than Windows Store apps, there is a risk that a URI scheme launched by a Windows Store app might compromise the system by launching a desktop app."
I haven't tried the registry setting, maybe that will also block normal desktop applications? Edit: it looks like the BlockProtocolElevation setting also only affects Windows Store apps.
WARNING: Do it at your own risk. I am fairly certain when I restart my computer, the Spotify app will no longer work as deleting the entry from the info.plist file most likely changes the signature of the app binary and it will no longer be valid.
Simply uninstalling the app won't be enough. Rebuild LaunchServices is required to get rid of the registered URL scheme.
The info.plist for Spotify for example is located at:
/Applications/Spotify.app/Contents/Info.plist
You can either do it through terminal or navigate to /Applications in finder, then right click the app and use "Show Package Content" option > Contents > Info.plist.
Open the Info.plist in Xcode, look for CFBundleURLSchemes:
<array> <dict> <key>CFBundleTypeRole</key> <string>Viewer</string> <key>CFBundleURLIconFile</key> <string></string> <key>CFBundleURLName</key> <string>Spotify Media</string> <key>CFBundleURLSchemes</key> <array> <string>spotify</string> </array> </dict> </array>
I removed this array. Save the file.
NOTE that if you previously had the app installed in a different directory, you might have to do it there too.
Once done, you will have to run this command to "Rebuild LaunchServices" as explained on this Stack Overflow post.
https://stackoverflow.com/questions/10156939/mac-show-delete...
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user
Without the above command, the URL scheme wasn't getting unregistered and the site was still picking it up.
Settings → Apps → Default apps → Choose default apps by protocol
Also there is Settings → Apps → Apps for websites, where you can control rerouting of http/https links to applications.
I'm not wildly keep on manually editing the registry, at least without someone else doing it first and reporting that it didn't break their computer :)
But unfortunately, this exploit is just depending on the popup to happen at all, which I don't think you can configure from Firefox. If a uri scheme handler is registered with Windows, Firefox will ask you if you want to use it. Deleting the registered scheme handler from Windows is a matter of finding an entry in HKEY_CLASSES_ROOT in the registry with a name that matches the scheme and deleting that entry. For instance, in regedit, if you find HKEY_CLASSES_ROOT\spotify, you can delete it and no more handler for spotify://.
Whether or not this breaks the program probably depends on the program. If buttons and links in the application itself use this scheme, then it probably will. If they're handled directly without delegating to the OS, then maybe not. Worst that happens is you can always just reinstall the application if it stops working.
I'm looking around through Firefox docs about whether it's possible to block specific uri schemes from being handled at all but not finding anything. They do block data:// and have a strict origin policy for file://, but those are already on by default and I can't find anything related to blocking (or allowing) arbitrary uri schemes. That would be one obvious fix, though, and the researchers here did report this as a bug, so maybe an upcoming Firefox will offer this.
Of course, if you do anything to allow hardware acceleration in your browser so you're not streaming media like it's 1999, it'll still be able to fingerprint you based on the hardware, but at least it won't see what applications you have.
- in Firefox, it detected Epic Games Telegram Discord Battle.net Xcode NordVPN Sketch Teamviewer Microsoft Word WhatsApp Postman Adobe Messenger Figma Hotspot Shield ExpressVPN Notion iTunes, none of which I have installed. It didn't detect VSCode though I have VSCodium.
- On Chromium, it warned it would not work well on Chrome on Linux. It incorrectly detected all the apps. It seems that the browser would try to open the links with xdg-open.
Clever hack anyway!
Security through obscurity does it again!
Edit: With firefox it is able to correctly detect 3 installed desktop applications.
in FF, unless im mistaken this assumes the user clicks anything except cancel on the popup. bug for reference and comment. https://bugzilla.mozilla.org/show_bug.cgi?id=1711084
further from the github:
> the basic concept is the same. It works by asking the browser to show a confirmation dialog in a popup window. Then the JavaScript code can detect if a popup has just been opened and detect the presence of an application based on that.
so...we seem to be relying on the honor system with the user? Can anyone clarify?
But I still have to look closer into it.
Something like that could still would be susceptible to a timing attack though.
Through it's maybe slightly more complex as you might need to behave as if the user clicked cancel in a way where a attacker can not easily differentiate it from an actual user clicking cancel.
I’m the article author, can you please clarify your question?
The demo will not work without a popup window in Chrome, Firefox and Safari. The “Get My Identifier” button is needed in order to have a single user gesture to open an additional window.
However the Tor Browser demo works silently without any additional window.
> ...
> Tor Browser has confirmation dialogs disabled entirely as a privacy feature, which, ironically, exposed a more damaging vulnerability for this particular exploit. Nothing is shown while the exploit runs in the background, contrasting with other browsers that show pop-ups during the process.
I'm on Firefox and didn't have to click anything. It correctly detected I have Steam installed.
The flashing popup window was quite obvious though.
But.. it wasn't unique for the second browser I tried. And they'd be coming from different IPs, so it wouldn't have any way to know both were coming from the same person, aside from the fingerprinting itself...
I've complained to many vendors and sent technical details of missed registry keys, files, etc. Sometimes they even fix it. But on the whole, Uninstall on Windows is a bit of a myth.
When you need privacy, always browse in a VM or a Tails boot.
https://fahrplan.events.ccc.de/congress/2016/Fahrplan/events...
But speaking of, does the website know if you do have MetaMask installed right away (without prompting you for anything)? Because that would be a real concern if it did.
And with a blindfold on your eyes.
Hope this won't be a post where everyone that didn't get the same identifier have to proclaim it, though. We get it, it's not perfect. FWIW I got same in Edge & Fx and it claimed it was a unique combo (different ID in Chrome, though).
This means exploitation requires Javascript, right? Tor browser users should have it disabled at all times.
Honestly, I believe it does not work at all.
> they are Mac-only application
I remember installing and using iTunes on Windows 7.
It might be that Apple doesn't distribute a modern version of iTunes. But it's certainly not true in the past.
Seriously, it maintains (among other things, yes) the mapping from filename extensions to the path of the binary that should be used to open them.
It's a map : extension -> path.
WhyTF does MIME have to get dragged into this? Why can't I just say "*.foo is opened with /usr/bin/foobalize"? Why must I suffer the agony of trawling the interwebs to find out that blartz.foo is actually a z-content-flavor/foobalized_v3? (Yes, I understand why browsers need to start the lookup using a MIME type. I'm talking about everything else -- the galaxy of things that don't use HTTP).
And even once I've found the Magic MIME type, xdg-open still does whatever it wants, and there appears to be no way to troubleshoot it when it's being invoked by another application. Setting XDG_UTILS_DEBUG_LEVEL=999 simply prints out a list of which files its reading (I can get that from strace, thanks), with no step-by-step rundown of its decision process:
$ XDG_UTILS_DEBUG_LEVEL=999 xdg-open ftp://foo.com
Selected DE generic
Checking /home/user/.config/mimeapps.list
Checking /home/user/.local/share/applications/defaults.list and /home/user/.local/share/applications/mimeinfo.cache
Checking /home/user/.local/share/applications/defaults.list and /home/user/.local/share/applications/mimeinfo.cache
Checking /usr/local/share//applications/defaults.list and /usr/local/share//applications/mimeinfo.cache
Checking /usr/local/share//applications/defaults.list and /usr/local/share//applications/mimeinfo.cache
Checking /usr/share//applications/defaults.list and /usr/share//applications/mimeinfo.cache
Checking /usr/share//applications/defaults.list and /usr/share//applications/mimeinfo.cache
Okay, y'all can downvote me now, ranty time is over.I've once had xdg-open be absolutely broken on my machine, scanning all of my $HOME because of a file with a space character in it [1]. Any attempt to use xdg-open would pin a CPU core for 100% while bash/find recursively traversed millions of files because of missing quote characters in a shell script. Truly the pinnacle of software engineering.
I wouldn't be surprised if serious security bugs lurked somewhere in it, exploitable by web pages attempting to open maliciously crafted protocol URLs.
[1] - https://github.com/freedesktop/xdg-utils/commit/9816ebb3e6fd...
- Document scripts are restricted, and can be customized and spoofed (or fully disabled) by the user.
- Whether or not a link can be opened, and whether or not it is asked, depends on user settings. If it is configured to ask, it does so for both known and unknown URI schemes.
- Known and unknown schemes are both considered different origins; they do not redirect to about:blank (unless it is a scheme which is handled by rendering a document, which happens to redirect to about:blank, but it does not normally do this).
- Scripts cannot detect such prompts, and only one can be displayed at a time. One key combination can be used to prevent further prompts; even if a way is found, only one will work anyways.
And many other improvements, because existing web browsers are bad in a lot of ways.
It does do the popup for VSCode asking if I want to open links there, which I do have installed.
I don't think you understood the core of the issue: it's not about identifying which applications you have installed, it's about always getting the same result for the same user. If all your browsers serve the same results, you are trackable, no matter if those results are good or not.
I.e. there are some schemas which lets say XCode handles but which also some other program handles.
Weird that when I tried running it in chrome headless[0], it opened the popup window, and tried the first scheme, but then stopped, and hung.
> most browsers have safety mechanisms in place designed to prevent such exploits. Weaknesses in these safety mechanisms are what makes this vulnerability possible.
> By specification, extensions need to be able to open custom URLs, such as mailto: links, without confirmation dialogs. The scheme flood protection conflicts with extension policies so there is a loophole that resets this flag every time any extension is triggered
If true, this sounds worse revelation than the exploit itself. Disabling a flag temporarily sounds bad, regardless of whether a vulnerability exists.
> We have generated your identifier based on 1 applications you have installed.
Skype
Then it told me I am ninety-something percent unique...I find that odd because pretty much every Windows machine has Skype.
You are likely relatively unique because you only have Skype installed, whereas a lot of visitors will have more applications out of the list. Someone who has no applications on the list installed may be even more unique, for example.
I ran it in a VM with Firefox and nothing else installed. It correctly detected nothing and stated:
> This is your identifier. It was seen 273 times among 3830 tests so far. > That means it is 92.87% unique.
What makes you assume I do not have Office installed? Instead of, say, considering the possibility that the fingerprinting may not be that good.
Tried again, same deal:
> That means it is 96.35% unique
I always get the same ID on the demo because 0 apps are detected :) and this makes the browser unique because not many people run browser on system with 0 apps installed.
I wish we could find a way to deal with this risk that's not simply disabling all kinds of functionality. Browser APIs seem to be suffering more and more by limitations to prevent finger printing.
Probably worse than you think. Zoom, Skype and Slack will be very common on work computers, while game launchers like steam and epic will work quite well on gaming pcs. You can differentiate further by checking the mixing of those groups and their relative music client (Spotify, ITunes...). Of course it won't be full 32 bits, but given the amount of quite common programs with url handler, it will probably deliver quite good results.
That is, assuming any of those happens to be installed and have a (input sanitation related) vulnerability.
Maybe I'm just seeing ghosts here. But the idea of a web site pushing malicious links to whatever software may also be installed on the same machine, isn't a very comforting thought.
For example, Safari opens the Apple Music without any user prompt. The app itself is designed to handle deep links (such as opening an album or starting the song).
That means you can perform a deep link forgery, in order to force the app to perform unwilling action without user confirmation.
I've seen popup-based exploits on less-legal websites (e.g. torrents, keygens, illegal streaming of live sports and/or movies) a few times over the years. I'm unsure if they're executing this specific exploit though.
That said, at least for tracking consistency is more important than accuracy.
On iOS (and MacOS too I believe), when developing apps and requesting URL scheme, the developer has to declare every URL scheme they want their app to query in the `LSApplicationQueriesSchemes` array in info.plist of the app. This was added in iOS 9 as part of a similar vulnerability where apps and advertisement SDKs would simply query a list of URL schemes and then identify based on that across multiple apps. Something similar can be done by browsers for websites. MacOS could simply show you a popup with a checkbox list of all URL schemes the site tries to query for with options for "Allow", "Deny" or "Randomize".
I didn't even notice the window flashing the first time round.
I'd say that this is a reasonably serious privacy vulnerability.
This is interesting since I didn't really expect Opera to care about this kind of thing.
I'd bet good money that this trick would be useful for anyone running either a meme generator website or a file host, for example. It'd be pretty solid in the file host in particular, because you could hide some of the obvious weird behavior behind the "We're downloading your file" delay.
All, except Word, were succesfully detected in Firefox though
On one of the browsers it also didn't detect slack and vscode being installed.
Is it you main browser in which you had used slack url's/ set slack to always handle the links?
Or is it the opposite?
Or maybe something else?
>This is your identifier. It was seen 2 times among 8828 tests so far.
None of these was my run. Still, didn't detect vscode :)
They are always going to exist for architectural reasons, some are worse than others, and the really bad ones are likely kept nice and secret while they are actively exploited. In other words, I'm not surprised in the slightest, but I'm glad that this is out in the open now.
I'm a bit surprised it got even one of them though. I will need to review my Brave privacy settings and see if anything can be done.
This only checks 24 apps, and it got all the ones I have installed out of those 24.
The internet connection may be the issue here, or the custom configuration on Safari.
I've updated the demo for Chromium and made it work slower, in order to increase accuracy.
Linux/Chrome
It's as if they want browser developers to look at the code and break it as much as possible.
E.g. user agent, screen dimensions, language, web GL, audio api, etc.
Generally wrt. fingerprinting chrome is worse then Firefox as Firefox actively worked to reduce fingerprint-ability if possible, while chrome seems to not care much. Because of this ironically I have a less unique fingerprint on a customized Firefox browser then a "stock" Chrome browser even through much less people use Firefox...
The reason (I think) why they make this public is because this can be used for more then "just" fingerprinting. I.e. this can be used by cyber attacks to find a potential attack vector to then pull of either a direct attack or some social engineering attack.
Ironically, many of the settings can make you more unique because they disable a lot of functionality.
Adding white noise is the only solution: "try to make your fingerprint on each website for each brower-restart look as different as possible (a) from your fingerprint on every other website and (b) from your fingerprint on the same website on a previous browser-restart".
That's the best you can do anyways without rejecting first-party cookies.
Brave does this, and it is the right way. I just wish Firefox would wake up and clue in to this.
> If you're seeing this message, that means JavaScript has been disabled on your browser, please enable JS to make this app work.
Does this mean that the vulnerability does not work in Tor Browser in Safest mode? Or are there non-JS implementations of this vulnerability that would work in a browser with JS disabled?
I glanced through the source[0] and my about:config and I noticed I have the dom.block_external_protocol_in_iframes setting enabled. Looks like this could be the mechanism they use? I don't remember enabling it manually.
Otherwise, it could be my tiling window manager messing with detection.
[0]: https://github.com/fingerprintjs/external-protocol-flooding/...
It's not very effective....
Chrome does not work on Ubuntu, since it opens everything with xdg-open and creates confirmation dialog for both installed and not-installed application