This works by looking for web accessible resources that are provided by the extensions. For Chrome, these are are available in a webpage via the URL chrome-extension://[PACKAGE ID]/[PATH] https://developer.chrome.com/docs/extensions/reference/manif...
On Firefox, web accessible resources are available at "moz-extension://<extension-UUID>/myfile.png" <extension-UUID> is not your extension's ID. This ID is randomly generated for every browser instance. This prevents websites from fingerprinting a browser by examining the extensions it has installed. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...
Doesn't the idea of swapping extension specific IDs to your browser specific extension IDs mean that instead of your browser being identifiable, you become identifiable?
I mean, it goes from "Oh they have X, Y , and Z installed" to "Oh, it's jim bob, only he has that unique set of IDs for extensions"
edit: er, I think that that also suggests that I need to restart firefox more often...
I presume the extension knows when it wants to access resources of its own. But random javascript, doesn't.
* if LinkedIn didn't take the data from an existing data source
LinkedIn's fingerprinting code, as the README explains, is found in fingerprint.js[2], which embeds a big JSON literal with the IDs of the extensions it probes for. (Sickeningly enough, this data starts about two-thirds of the way through the file* and isn't the culprit behind the bulk of its 2.15 MB size…)
* the one (on line 34394) starting:
const r = [{
id: "aacbpggdjcblgnmgjgpkpddliddineni",
file: "sidebar.html"
1. <https://github.com/mdp/linkedin-extension-fingerprinting/blo...>2. <https://github.com/mdp/linkedin-extension-fingerprinting/blo...>
They could stop all the scraping by providing a downloadable data bundle like Wikipedia.
The data bundle doesn't help that at all.
This is a popular position across the aisle. Here's hoping the next guy can't be bought, or at least asks for more than a $400M tacky gold ballroom!
The recruiters all had LinkedIn paid accounts, and could access all of this data on the web. We made a browser extension so they wouldn’t need to do any manual data entry. Recruiters loved the extension because it saved them time.
I think it was a legitimate use. We were making LinkedIn more useful to some of their actual customers (recruiters) by adding a somewhat cursed api integration via a chrome extension. Forcing recruiters to copy and paste did’t help anyone. Our extension only grabbed content on the page the recruiter had open. It was purely read only and scoped by the user.
https://javascript.plainenglish.io/the-extensions-you-use-ar...
Screenshots found here https://x.com/DenisGobo/status/2018334684879438150
https://blog.castle.io/detecting-browser-extensions-for-bot-...
Typical early hooks: • fetch wrapper • XMLHttpRequest.prototype.open/send wrapper • WebSocket constructor wrapper • history.pushState/replaceState wrapper • EventTarget.addEventListener wrapper (optional, heavy) • MutationObserver for DOM diffs • Error + unhandledrejection capture
I get that the CSV lists the extensions, and the tools are provided in order to show work (mapping IDs to actual software). But how was it determined that LinkedIn checks for extensions with these IDs?
And is this relevant for non-Chrome users?
https://blog.castle.io/detecting-browser-extensions-for-bot-...
I didn't find popular extensions like uBlock or other ad blockers.
The list is full of scammy looking data collection and AI tools, though. Some random names from scrolling through the list:
- LinkedGPT: ChatGPT for LinkedIn
- Apollo Scraper - Extract & Export Apollo B2B Leads
- AI Social Media Assistant
- LinkedIn Engagement Assistant
- LinkedIn Lead Magnet
- LinkedIn Extraction Tool - OutreachSheet
- Highperformr AI - Phone Number and Email Finder
- AI Agent For Jobs
These look like the kind of tools scummy recruiters and sales people use to identify targets for mass spamming. I see several AI auto-application tools in there too.
cut -d',' -f2 chrome_extensions_with_names_all.csv | grep -c "AI"
474
Only 16%!?1. Bot prevention. If the bots don't know that you're doing this, you might have a reliable bot detector for a while. The bots will quite possibly have no extensions at all, or even better specific exact combination they always use. Noticing bots means you can block them from scraping your site or spamming your users. If you wanna be very fancy, you could provide fake data or quietly ignore the stuff they create on the site.
2. Spamming/misuse evasion. Imagine an extension called "Send Messages to everybody with a given job role at this company." LinkedIn would prefer not to allow that, probably because they'd want to sell that feature.
3. User tracking.
I would guess this is for rate limiting and abuse detection.
You can try this by opening devtools and setting
localStorage.setItem('hi', 123)(Alternatively extension developers can modify their extensions to block these requests!)
Does Firefox have a similar weakness?
[1]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...
[2]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...
Edit: Can't find much documentation on exactly how the anti-fingerprinting works, but this page implies that the browser blocks extension detection: https://support.mozilla.org/en-US/kb/trackers-and-scripts-fi...
Which would probably wreak havoc with a lot of web apps, at least requiring some kind of same-origin policy. And maybe it messes with OAuth or something. But it does seem at least feasible.
Browsers already have strong protections against that sort of thing, look up the same-origin policy and CORS
Should be patched nonetheless though, that's a pretty obscene fingerprinting vector.
The file is then available using a URL like: moz-extension://<extension-UUID>/images/my-image.png"
<extension-UUID> is not your extension's ID. This ID is randomly generated for every browser instance.
This prevents websites from fingerprinting a browser by examining the extensions it has installed.Why can't it just deny access to the specified path, except to the extension itself?
- why does CWS respond to cross-site requests?
- why is chrome sending the credentials (or equivalent) in these requests?
- why is the button enabled server-side and not via JS? Google must be confident in knowing the exact and latest state of your installed extensions enough to store it on their servers, I guess
Edit: Confirmed. It's not pinging the Chrome Web Store. https://blog.castle.io/detecting-browser-extensions-for-bot-...