I'm a huge privacy advocate, and I use a number of plugins to help protect my privacy from trackers around the web.
Occasionally, there is functionality that I really want in my browser, and a plugin that offers exactly what I am looking for, but from a company I don't know. I dislike giving such a plugin access to my data - it has so much potential for abuse alongside the benefits. As a result, I generally do some basic analysis before installing and using it.
In general, I believe a plugin should be sending zero data. In some cases, however, a service must send data to a third party to perform its intended function. In these cases, we want to ensure the data being sent is appropriate for the requested service and then make an informed decision about how we feel about that data being sent.
In this article, I will walk through the typical steps I take to check if any of my data is being sent somewhere I don't like, and then sharing my analysis of the top 10 plugins in Firefox and Chrome:
- First, I will talk about general non-technical steps to take to get a feel for how benign a plugin is.
- Second, we will learn to intercept and inspect any traffic sent by the browser. This can be done by anyone willing to get their hands dirty, without any special technical expertise.
- Third, we will learn how to bypass plugin encryption or obfuscation techniques that try to hide what data is being sent. This section requires a little more know how, but is not hard to learn - generally the first step tells you all you need to know in any case (If you need to do it, you probably shouldn't trust the plugin anyway!)
This process won't catch everything - tricky authors can work around these detection measures. I won't be doing an in depth source code review, for instance.
As an example, we'll take a look at the Web of Trust plugin, which is marketed to security conscious consumers, but has had some significant negative press. Then I'll show summary results for the most popular plugins in the Firefox and Chrome marketplaces.
About the Web Of Trust Plugin on FireFox
Web Of Trust sounded like a good idea when it came out - a service that allows users to rate how trustworthy a site is, and a plugin to report an icon relating that information.
This is a good example of a service that has a valid reason to send some personal data back to a central service - it needs to check the URL you are visiting against it's own database, and return a trustworthyness score and other metadata to the browser.
Unfortunately, in 2016 they were caught selling personal browsing data. According to Wikipedia:
"The NDR investigative journalism report was based on freely available sample data, and revealed that sensitive private information of more than 50 users could be retrieved. The information included websites visited, account names and email addresses, potentially revealing user illnesses, sexual preferences and drug consumption. The journalists also reconstructed a media company's confidential revenue data, and details about an ongoing police investigation"
WOT was removed and then later re-instated in the FireFox plugin directory, so let's see what they are up to now.
Basic Plugin Intelligence Gathering
I always start by looking at and researching plugin authors, reading comments, and digging around for any other information - often this can tell all you need to know about a plugin, and is a critical part of determining add-on safety.
For WOT, a simple search would have found the Wikipedia article above, which should be enough to warn you away.
In addition, the 1 star review page is full of links to articles about privacy concerns and ads.
But what about lesser known plugins, or plugins that haven't had as much press? We may not find anything in reviews or searches, but that doesn't mean we should trust it.
Safely Installing WOT and Intercepting Data Sent
I treat unknown browser plugins the same way I would treat malware, though I admit this might be a little bit of overkill. For this post, I created a VM with a fresh install of Ubuntu and FireFox, since I didn't want to use my real browser.
Installing ZAP Web Proxy
I'm only going to need a couple of tools for this: ZAP, a web proxy for intercepting web traffic, and the Mozilla debugging tools for plugins. ZAP can be installed with snap:
$ sudo snap install zaproxy --classic $ zaproxy
ZAP should start up in a new window - go ahead and select "do not save session" since we will only be using this briefly.
We will also want to setup FireFox to accept ZAP's SSL certificates so ZAP can properly intercept traffic to https sites. In Zap, navigate to tools->options and in the window that comes up, choose Dynamic SSL Certificates. You should see a window with a bunch of data that starts with
-----BEGIN CERTIFICATE-----. Click the Save button and put this anywhere in your home folder.
Open Firefox, and go to Preferences -> Privacy & Security -> Certificates. Choose View Certificates and then Import. Choose the .cer file you saved from ZAP and import it, trusting it to sign for websites.
Let's go ahead and install WOT. I don't want to give them a link, but you can find them pretty easily in the plugin store by searching for WOT or web of trust.
When everything is installed and working, restart Firefox to get a clean browser session with no open tabs.
Intercepting Data Sent
We'll now configure FireFox to intercept data sent using ZAP. If you haven't used something like ZAP before, it's an attack proxy, an extremely powerful tool for website security analysis. Here we will be using it in a very limited way, so don't be intimidated by all the options and information you see.
To get firefox to send all traffic through ZAP, open preferences once again and in the Network section, change the proxy settings to point to localhost:8080 for all kinds of traffic.
Alright! Let's see what kinds of things WOT sends. I'm going to type www.Wikipedia.org directly into my browser, click the daily featured link, and see what we get.
We can ignore all the folders that show links to places we might expect, like Wikipedia and Mozilla sites, and focus only on the mywot.com domain.
It doesn't look like a ton of data, but it's not fully clear what is being sent. The fields seem simple, a target, nonce, language, plugin version, etc. Then there is that long b64 field.
At this point, you might have seen enough to make a decision - most plugins shouldn't send any data, and now we know WOT is sending something, though we don't know quite yet what it is - it's encoded!
Decoding the b64 Field
You might recognize this b64 field as base64 encoding. So let's decode it and see what we get! Linux includes the handy
base64 command line tool, we can use it to extract information:
$ echo "aWQ9ODlmOWZkNDhiY2E0NjM1ZjIxMDUzYjg0ZDQ5NGJiZTc3ZjQwNTY4MyZub25jZT05OTQ0MjZmMmUwOGE5NThiNTUyMDZmMzkyZTA2ZDQ0NDQ5ZGJhNWJjJmxhbmc9ZW4tVVMmdmVyc2lvbj00LjAuMTAuMjEtMjAxNzA4MDEtMy4yLjImdGFyZ2V0PUptVWhDN2kwQmhvR1hsS1dzSkt6NEZYT3AlMkZieUpnaThBRUYlMkJVbGlYRjVGN1BZRVQyRmx2RGM3S2JwUUIlMkZwQnJLZlpQeFJtcjRTNkhwTGVTU1VYck5ueFVYajkzekM4M05ZaVoyeno0dzJxY3hua01FRENHM01DQkNPM2t0SjdmeVUzYWhldTVYZ2tvY216QUlSU0VhQXhpSFhtRHlSVzNSa3o5M2JDS1laQ0kxJTJGJTJGM29KT2sybVk1U2ROVHJRaWN3QnJ5SWE3S1NQWVpFcmppam1Wa3NtSjVRb2lmU1hMRjlHa1BuTnlGOVMlMkJpWXBGaU14SE0xZUklMkZZcFNYTDVvSUclMkZNcktoQ0VBV2dCMHpPSDZCbU5OZGhvYmNLUHVVY0RHRiUyRjZCNkQlMkZSZ0FJUGlJaE1rdUZuWnp0TENjM2sxd1B6a281dldnU28wUWltZXl5bG4wZiUyRllacHFlenBYRnVxeDFVZ3ZuelhGcWwxN1JqdUJiT2RlZ0drTGZWanU4aGY5WmNTakF3biUyRmV5eGViNDhwRm1oRlYzcFpGSzlNZzlnRkhyMWN4T3B4Q3doQ2VYd3NSdUsyWE5hM3E2UWNjYzNjOUE3cnh2OEFPSXMlMkJjM0JqUGdjbG9nWkc1U2pIeHNnc1kzaGozak5UWDU0RjQ2TlZVOCUzRA==" \ | base64 --decode id=89f9fd48bca4635f21053b84d494bbe77f405683& nonce=994426f2e08a958b55206f392e06d44449dba5bc& lang=en-US& version=22.214.171.124-20170801-3.2.2& target=JmUhC7i0BhoGXlKWsJKz4FXOp%2FbyJgi8AEF%2BUliXF5F7PYET2FlvDc7KbpQB%2Fp BrKfZPxRmr4S6HpLeSSUXrNnxUXj93zC83NYiZ2zz4w2qcxnkMEDCG3MCBCO3ktJ7fyU3aheu5X gkocmzAIRSEaAxiHXmDyRW3Rkz93bCKYZCI1 %2F%2F3oJOk2mY5SdNTrQicwBryIa7KSPYZErjijmVksmJ5QoifSXLF9GkPnNyF9S%2BiYpFiMx HM1eI%2FYpSXL5oIG%2FMrKhCEAWgB0zOH6BmNNdhobcKPuUcDGF%2F6B6D%2FRgAIPiIhMkuFn ZztLCc3k1wPzko5vWgSo0Qimeyyln0f%2FYZpqezpXFuqx1UgvnzXFql17RjuBbOdegGkLfVju8 hf9ZcSjAwn%2Feyxeb48pFmhFV3pZFK9Mg9gFHr1cxOpxCwhCeXwsRuK2XNa3q6Qccc3c9A7rxv 8AOIs%2Bc3BjPgclogZG5SjHxsgsY3hj3jNTX54F46NVU8%3D
We get a different id and nonce, and a new target field that has some data that looks url encoded. Let's decode it (Here I use some Python to decode the URL - but if you search URL decoder, plenty of web pages can also do this).
$ export target="JmUhC7i0BhoGXlKWsJKz4FXOp%2FbyJgi8AEF%2BUliXF5F7PYET2FlvDc7KbpQB%2FpBrKfZPxRmr4S6HpLeSSUXrNnxUXj93zC83NYiZ2zz4w2qcxnkMEDCG3MCBCO3ktJ7fyU3aheu5XgkocmzAIRSEaAxiHXmDyRW3Rkz93bCKYZCI1%2F%2F3oJOk2mY5SdNTrQicwBryIa7KSPYZErjijmVksmJ5QoifSXLF9GkPnNyF9S%2BiYpFiMxHM1eI%2FYpSXL5oIG%2FMrKhCEAWgB0zOH6BmNNdhobcKPuUcDGF%2F6B6D%2FRgAIPiIhMkuFnZztLCc3k1wPzko5vWgSo0Qimeyyln0f%2FYZpqezpXFuqx1UgvnzXFql17RjuBbOdegGkLfVju8hf9ZcSjAwn%2Feyxeb48pFmhFV3pZFK9Mg9gFHr1cxOpxCwhCeXwsRuK2XNa3q6Qccc3c9A7rxv8AOIs%2Bc3BjPgclogZG5SjHxsgsY3hj3jNTX54F46NVU8%3D" $ echo $target | python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.stdin.read()));" JmUhC7i0BhoGXlKWsJKz4FXOp/byJgi8AEF+UliXF5F7PYET2FlvDc7KbpQB/pBrKfZPxRmr4S6HpLeSSUXrNnxUXj93zC83NYiZ2zz4w2qcxnkMEDCG3MCBCO3ktJ7fyU3aheu5XgkocmzAIRSEaAxiHXmDyRW3Rkz93bCKYZCI1//3oJOk2mY5SdNTrQicwBryIa7KSPYZErjijmVksmJ5QoifSXLF9GkPnNyF9S+iYpFiMxHM1eI/YpSXL5oIG/MrKhCEAWgB0zOH6BmNNdhobcKPuUcDGF/6B6D/RgAIPiIhMkuFnZztLCc3k1wPzko5vWgSo0Qimeyyln0f/YZpqezpXFuqx1UgvnzXFql17RjuBbOdegGkLfVju8hf9ZcSjAwn/eyxeb48pFmhFV3pZFK9Mg9gFHr1cxOpxCwhCeXwsRuK2XNa3q6Qccc3c9A7rxv8AOIs+c3BjPgclogZG5SjHxsgsY3hj3jNTX54F46NVU8=
We get some more encoded text. It looks like base64 again (After a while base64 sticks out visually. A good indicator is data ending in one or two = signs, though there are base64 strings with no trailing equal signs), so we'll run it back through a base64 decoder:
$ echo $target | python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.stdin.read()));" | base64 --decode &e! ��n���k)�O���.����IE�6|T^?w�/75���<��j��y 0����䴞��Mڅ��^ (rl�!�h by���FL�ݰ�a���������f9I�S���!��H����ed�byB��Ir��i�܅�/�b�b3���?b��/�+*�h�3���5�hm�G_���>"!2K����,'7�\�J9�h�D"�첖}��i���\[��U �|��u����z�-�c��_��� '���y�<�Y�]�dR�2`z�s��,! �����sZޮ�q�7s�;���,��������� ����x�M~x��UO ```
Looks like binary data. When I see binary data, I usually suspect encryption. It's possible they are using a technology like protobufs, or special encoding to save bandwidth. Either way, this brings us to the end of this method of inquiry but definitely raises my suspicions. Why does this plugin send binary data?
Analyzing WOT Source Code
Let's look at their source code and see if we can determine where they are generating the binary data from.
To get the source, all we need to do is pull down and extract the plugin file.
$ wget https://addons.mozilla.org/firefox/downloads/file/998298/web_of_trust_mywotwot_website_reputation_rating-20180622.0wot-an+fx.xpi $ unzip wget https://addons.mozilla.org/firefox/downloads/file/998298/web_of_trust_mywotwot_website_reputation_rating-20180622.0wot-an+fx.xpi $ cd wot
wotCrypto.js in the
scripts/shared/ directory. It has some code to encrypt and encode data being sent, and makes use of the nonce in the data we saw earlier.
We could try to take the decrypt function and pass our data to it in some way, but I find it's much easier to debug the plugin and see everything in real time.
Setting up the Firefox Plugin Debugger
In a new Firefox tab, enter
about:debugging into the URL bar. You should get a page with all your addons. Check the box to enable debugging and click the debug link below the WOT add-on.
Allow the browser to connect to the debugger, and choose the "debug" tab. Navigate to the
scripts/shared/wotCrypto.js file, then scroll to line 302, where the
encrypt function starts. Click the first line number within the function (303) to set a break point at this point in the code. The debugger should highlight the line with an arrow to show that execution will stop when the plugin enters this function.
Let's browse around wikipedia a little more, and see what comes up here. After clicking a link, the pane on the right populates with some information as our breakpoint was hit.
I see some url encoded data to be encrypted. If I run it back through the URL decoder, we can see what is about to be sent:
$ echo "host=en.wikipedia.org&subtrgt=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FChemical_species&sublast=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FChemical_element&subref=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FChemical_element&vmt=4&sg=abb46fd76&delta=AEAAAAAAAAbAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA%3D&format=1&ver=126.96.36.199&epochtime=1547130951403&id=cc14b627e77e439fb4f4ad1287b0612d8a8a8428" | python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.stdin.read()));" host=en.wikipedia.org&subtrgt=https://en.wikipedia.org/wiki/Chemical_species&sublast=https://en.wikipedia.org/wiki/Chemical_element&subref=https://en.wikipedia.org/wiki/Chemical_element&vmt=4&sg=abb46fd76&delta=AEAAAAAAAAbAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA=&format=1&ver=188.8.131.52&epochtime=1547130951403&id=cc14b627e77e439fb4f4ad1287b0612d8a8a8428
It looks like there are four main data components here:
- host (wikipedia)
- target (the full url including the specific page I am visiting)
- last (the page I visited last) and
- referrer (the referring page)
To perform their service, they only really need the host - everything else is data that I would prefer they did not send. Because my browser is sending this in a standard web POST request, they will also receive browser fingerprint data that all sites receive like my browser user agent, IP address, and any saved WOT cookies.
Opening a new tab in a new page will set the last page to the URL in the tab I last had open - so they can also tell how I am moving between sites that are not linked via a click. Nasty!
So they end up with a lot of data. Not very nice.
WOT also slurps up other tracking data
If we try browsing around on Google or other sites that send tracking information about us around the web, a lot of that is captured by WOT as well. Doing a simple google search and clicking on the first result had this data being sent up to WOT:
A lot of that is Google tracking code, which uses a combination of base64 and protobufs. Extracting out the "reason" information gives WOT some more information they could use if so inclined:
|as[[[[null,,null,null,null,["80425"]],[null,null,[null,null,null, "https://displayads-formats.googleusercontent.com/ads/preview/content.js? client=wta\u0026 obfuscatedCustomerId=3429531957\u0026 creativeId=303434743861\u0026versionId=0\u0026 adGroupCreativeId=277244291015\u0026 htmlParentId=prev-0\u0026height=0\u0026width=0\u0026sig=ACiVB_xh6wu3jNojYrm3RZbozuLgtm7MAA"]]]]]
This is on a fresh VM with a brand new browser and my first google search. It is possible this would contain more information as my local profiles grew. Yikes!
Analyzing the Top 10 Firefox Plugins
I did a minimal analysis of the top ten Firefox plugins, as sorted by usage. Here are my findings:
- AdBlock Plus: Sometimes sends a ping back to notification.adblockplus.org, but nothing I could see that was malicious.
- Ublock Origin (a plugin I personally use): No data sent that I could find.
- Video Download helper: No data sent that I could find. I tried downloading a youtube video, and it asked for me to install a companion app, which I did not test.
- Easy Screenshot: No data sent that I could find.
- Cisco Webex: Sends data on first install with some basic telemetry (showing that it was loaded), then again every time the browser is started. I couldn't get it to trigger on any other action.
- NoScript (Another plugin I personally use): Thankfully, I do not see it sending any data.
- Avast Security: Marketed as protecting users from security issues, but this sends even more data out than WOT. For instance it sends all data from google search results. It appears they also have the ability to view local IP addresses and location data. Thankfully, there is an option to disable this which seems to be honored in the code.
- AdBlock: Does not seem to send any data, in contrast to adblock plus above.
- Ghostery: It sends the most data of the top 10 apps, and nearly all of it binary blobs. I didn't spend time analyzing what is being sent exactly, but a glance through the (obfuscated) code doesn't look promising. They were acquired by clickz, a media company, in 2017.
- Yandex Visual Bookmarks: The plugin is in Russian, so I don't know much about it. Upon install, it asks for massive amounts of permissions (access to recently closed browser tabs?), and sends data to 20 different domains. After that, it seems relatively mild, mostly doing GET requests occasionally to retrieve updates.
Analyzing the Top Chrome Extensions
The chrome store doesn't seem to have a sort by installed number list available, but I found a couple of lists of top extensions that had 10M+ installs. There is some overlap with Firefox add-ons, and I did not re-evaluate them, since they likely use largely the same code base and behaviors.
- Adblock: Evaluated with Firefox
- Adblock Plus: Evaluated with Firefox
- Avira Browser Safety: It claims to reduce tracking. It does send each URL you visit back to the Avira servers, along with a session token. Unlike the other tools I looked at in this category, it does not seem to track anything but the domain you visit, which is good!
- Avast Security: Evaluated with Firefox
- Hola Proxy Unblocker: Hola was caught using users bandwidth for other paid users, including in botnet like DDOS attacks. It's not a good plugin to use. It has many users in Chrome, and almost none in Firefox. Because it is a proxying software, as you might expect, all your web traffic passes through the Hola network.
There were also several Google based extensions I did not test in the most used plugin list.
Extensions are a dangerous thing, though sometimes they are the best way to enhance your productivity.
Use caution when installing new plugins - some of the worst offenders are those claiming to enhance privacy and security. When in doubt, try following the steps in this article to see for yourself what the plugins are doing.