Hidden in plain sight: the risks of browser extensions (1/2)

Hands up if you’ve customized your browsing experience with extensions. Perhaps you’ve added an ad blocker, or one to check your writing, or even one against fingerprinting. However, what if these extensions weren’t as secure as you thought – and actually posed a real risk to your online activity?

Our research has revealed exactly these far-reaching dangers of browser extensions, including real-life examples of extension detection by some of the world’s most used platforms. In this two-part series, we explore the methods and risks of extension detection, and then look further at their prevalence, privacy implications and mitigation.

The basics: browser extensions v plugins

Browsers are a vital part of our internet life, used hundreds of times daily to read the news, access accounts, send emails and run our businesses. However, instead of trying to meet everyone’s special needs, Lego-style (“Only the best is good enough” – “Det bedste er ikke for godt“, as the motto goes), browser vendors leave customization up to the developer community by offering browser extensions or add-ons. As with Lego, it’s possible to customize browsers for different needs just by putting pieces, like HTML, CSS, JavaScript, together.

That said, many of us are prone to confusion about two similar terms: plugins and extensions.

While plugins are executable binaries, extensions are script codes that use APIs exposed by browsers. While some plugins like Adobe Flash are deprecated by almost every browser vendor, extensions are still widely used every day.

Extensions are widely used every day. However, like everything, they are not without downsides, as we will discover.

Putting their uses in a box is almost impossible. There are 84 categories offered by the most used extension market, Google Chrome Store, ranging from productivity to weather forecast, cryptocurrencies, dating, fashion and more.

Unfortunately, like in the real world, each comfort comes with its own cons in the digital world. It’s not unreasonable, then, to ask if installing extensions can damage your privacy. And the answer is telling.

Risks inherent to browser extensions

When you accept the permissions extensions ask from you, they can have powerful abilities like reading browser history and cookies, or intercepting requests and responses. Although these risks are not in the scope of our article, we consider it important to warn you that, not just before installing, but after updating an extension, it may ask for some extra permissions from you. A further threat comes from the risk of a browser extension or add-on being sold out to another developer or company, who could then use it to harvest data for malicious purposes.

Let us, however, move onto the issue of browser fingerprinting.

Extensions as part of browser fingerprinting

Picture from the search Extension Breakdown: Security Analysis of Browsers Extension Resources Control Policies - 2017
Picture from the search Extension Breakdown: Security Analysis of Browsers Extension Resources Control Policies – 2017

Are browser extensions detectable? In contrast to plugins, browsers don’t offer a method like navigator.plugins to get a list of installed extensions in one go. However, extension detection has been known to be possible for some time, beginning with empirical works and blog posts in 2007, moving through to in-depth research from 2014 onwards. At first, when it was only individuals asking the question, it was also possible to see browser fingerprint codes as part of an XSS Exploitation framework BeeF.

Our knowledge has, however, developed rapidly. Here we look at four key areas of browser extension detection.

1. Web Accessible Resources (WAR)

Extensions are archive files that contain many resources like JavaScript, HMTL, CSS and image files. Web Accessible Resources is a method whereby a website can access the files of an extension that are stored on your computer and thus understand if the extension is installed.

A folder view of NoScript browser extension.
A folder view of NoScript browser extension.

Starting from the early days of extension detection, research has focused on using these to detect extensions’ existence. Having a unique 32-character extension identifier in Chrome certainly helped that aim. For instance, when the identifier and resources of an extension is known, a basic code such as the below could help websites understand if that extension is installed and active on the browser.

<img src=”chrome-extension://AN_IMAGINERY_EXT_ID/IMAGINERY_RESOURCE.png” onload=”alert('Extension exists');” oneror=”alert('Extension does not exist');”/> 

While this detection mechanism worked for all extension files, Google Chrome suggested a prevention mechanism against extension detection in the form of manifest.json version 2 in 2013.

According to this update, only the files that are defined in the section of web_accessible_resources (WAR) node of manifest.json can be loaded out of the extension – that is to say, by websites.

Web Accessible Resources

Up to 2019, this method had been used both in academic research and in the wild to detect extensions.

2. DOM alteration

Until this point, we in the sector had largely been focused on ways of probing extensions. However, in 2019, we became aware that many extensions reveal themselves through DOM alteration. Essentially, this means changes to the source code of a page that aren’t directly seen, but allows on further inspection the revelation of these changes and eventually the ability to spot an extension.

This also gave rise to the idea that the extension ID randomization mechanism Firefox applies to prevent extension probing actually poses another, more important risk: making it possible for a randomized ID to be used for a malicious website to track a unique user.

Firefox’s extension ID randomization actually poses a serious risk in itself, by creating a randomized ID that a malicious site can use to track a user.

So how does DOM alteration work? Browser extension affects the DOM of a page in several ways. By observing these DOM changes, it is possible to detect a browser extension. For example, widely used browser extension Grammarly, downloaded by over 10 million users, has this exact effect by adding an attribute, data-gr-ext-installed, to the document body. Therefore, by using a code such as the following, it’s possible to detect this extension.

if(document.body.hasAttribute("data-gr-ext-installed")) alert("Grammarly Detected");

Even some extensions specifically designed to protect you in fact create the same risks. It is important to highlight here that many people prefer browser extensions to protect themselves from browser fingerprinting. However, these kinds of extensions have a direct effect on DOM and other browser objects. Because of the traces left behind, most of the time, detecting them is easier than others. Take WebGL Fingerprint Defender (olnbjpaejebpnokblkepbphhembdicik), which allegedly defends against WebGL fingerprinting., as an example of DOM alteration.

if(document.documentElement.dataset.hasOwnProperty("wgscriptallow")) alert("WebGL Fingerprint Defender");

Another example is the extension Don’t Fingerprint Me (nhbedikkbkakbjipijipejfojanppbfg), which has a direct effect on the window object. It adds an attribute to window object, dfpm, and its whole length is 3689 characters long.

Extensions like Don’t Fingerprint Me, allegedly protecting you, are in fact easily detectable.

As for the case of Firefox? Imagine that you load an extension resource inside a page using an extension URL that includes a randomized extension ID: a malicious website can obtain this randomized ID and track the user. Firefox developers claim that randomized IDs are created each browser instance. However, research shows that even when browser history is deleted or the browser is updated, these randomized IDs stay the same. See below a table of situations where randomized IDs are changed or not.

When do randomized IDs change?
When do randomized IDs change?

This means that if you’re managing multiple accounts and trusting Firefox to protect your identity, you’re on shaky ground. Recent research backs this up, showing that with a combination of revelation and probing attacks, a massive 90% of extensions injecting content are identifiable, in spite of randomization.

It is important to note that whenever an instance of Stealthfox in Multilogin is started, randomized IDs are regenerated. In other words, if your business uses Multilogin, this type of attack is impossible.

It is important to note that whenever an instance of Stealthfox in Multilogin is started, randomized IDs are regenerated. In other words, if your business uses Multilogin, this type of attack is impossible.

3. Behavioral analysis

Some extensions don’t use WARs and don’t have any side-effect on DOM. However, it is still possible to detect them just by observing some behaviors that they cause. For example, the extension uBlock Origin is used to block advertisements. Although the extension whitelists some pages to be used as WAR, it also tries to prevent accessing them internally. Normally, if you try to access a document that is not whitelisted in manifest.json, the resource is going to be routed to chrome://invalid URL. However, in uBlock Origin, because the extension itself tries to intervene, the URL is not routed to chrome://invalid. It stays as it is. We can identify the extension by using this behavior.


<link rel="prefetch" href="chrome-extension://cjpalhdlnbpafiamejdnhcphjbkeiagm/web_accessible_resources/1x1.gif"/> 
<script> 
if(performance.getEntriesByName("chrome-extension://cjpalhdlnbpafiamejdnhcphjbkeiagm/web_accessible_resources/1x1.gif").length>0) { detectedPlugins.push("UBlock Origin"); 
} 
</script>

4. Internal messaging or external resource loading

A browser extension consists of several parts, such as the content script, background script, manifest.json file and its resources. While the content script is part of the loaded web page, the background script runs, as the name implies, in the background. Due to the security model designed by browser vendors, these parts are isolated and cannot reach one another directly. They have to use an internal messaging mechanism like extension APIs or window messaging to communicate with each other.

An extension can also whitelist some URLs by using an externally_connectable instruction in its manifest.json file, and this whitelisted webpage can then use runtime.sendMessage API to send a message. However, this instruction externally_connectable does not allow wildcard use and needs at least a second-level domain. Nevertheless, extensions can need to communicate with web pages in either way. Some extensions, such as MeetMe Dolby Voice 1.1 (lflnplggpolkcgknahacafilopgngelc), use the window postMessage method to send and receive messages between the content script and web page.

Content script of MeetMe Dolby Voice 1.1. Extension
Content script of MeetMe Dolby Voice 1.1. extension

Any arbitrary website can listen to this message and fingerprint the extension by using this method. In addition, some extensions also load extra resources as well as web-accessible resources of the extension itself, and these resources can be observed by using Performance API, like performance.getEntries(“resource”).

In this first part of our series, we have looked at how easily detectable browser extensions are – including those designed to supposedly protect you. For anyone who has built a business managing multiple accounts relying on extensions like these, we must emphasize the importance of these risks.

Don’t miss Part Two, in which we will discuss the prevalence of extension detection in the wild, including on popular platforms like LinkedIn and YouTube, and we will talk further about mitigation strategies. Watch this space and be sure to subscribe to our emails so you never miss an update.