CSP is Dead,
Long Live CSP
On the Insecurity of Whitelists and the
Future of Content Security Policy
Lukas Weichselbaum
Michele Spagnuolo
Sebastian Lekies
Artur Janc
ACM CCS, 2016, Vienna
Slide 2
Slide 2 text
About Us
We work in a special focus area of the Google security team
aimed at improving product security by targeted proactive
projects to mitigate whole classes of bugs.
Michele Spagnuolo
Senior Information Security
Engineer
Lukas Weichselbaum
Senior Information Security
Engineer
Slide 3
Slide 3 text
Research Questions
TL;DR: is CSP protecting against XSS?
1
Slide 4
Slide 4 text
Research Questions
◉ How is CSP used on the web?
◉ Do deployed CSPs protect against XSS?
◉ Do CSP whitelists work in practice?
◉ Is there a better way to effectively mitigate XSS?
Slide 5
Slide 5 text
Recap: What is CSP?
◉ An HTTP header developers can use to lock down
their web applications in various ways.
◉ A defense-in-depth mechanism - it reduces the
harm that a malicious injection can cause, but it is
not a replacement for careful input validation and
output encoding.
Slide 6
Slide 6 text
Recap: How does CSP work?
Script injections (XSS) get blocked
Content-Security-Policy
default-src 'self';
script-src 'self' yep.com;
report-uri /csp_violation_logger;
money.example.com money.example.com
yep.com
attacker.com
">'>alert(42)
money.example.com/csp_violations_logger
CSP
blocks
inline script
not allowed
">'><script
src="//attacker.com">
CSP
blocks
source not
whitelisted
CSP
allows
CSP
allows
Slide 7
Slide 7 text
Data Set
Internet-wide analysis on the full Google index (approximately 100 billion pages)
2
Slide 8
Slide 8 text
Collecting CSPs & Bypasses
WWW Google Index
100 Billion pages
CSP
Filter
1.6 Million
Hosts with
CSP
CSP
Dedupe
26,011
unique CSPs
In addition to the CSPs, we also
collected JSONP endpoints and
Angular libraries (whitelist bypasses)
JSONP
Filter
8.8 Million
JSONP
endpoints
Angular
Filter
2.6 Million
Angular
libraries
Slide 9
Slide 9 text
Normalize & de-duplicate CSPs
◉ Problem 1: CSP can have variable parts (e.g. nonces)
◉ Problem 2: Same CSP on thousands of hostnames
○ Caused by off-the-shelf web applications
■ e.g., message boards and e-commerce platforms
○ De-duplication by hostname/CSP would have been strongly
biased
◉ De-duplication based on the normalized CSP string
CSP Use Cases
All Unique Policies
This data set contains
all unique CSP
policies, both in
report-only and
enforcing mode.
XSS Policies
● enforced
● at least one of:
○ script-src
○ object-src
○ default-src
Strict XSS Policies
Like XSS Policies, not
including unsafe
directive values as:
● 'unsafe-inline'
● a URI scheme
● the * wildcard
26,011
unique CSPs
86% 11%
Slide 12
Slide 12 text
CSP Evaluation
Assess whether a CSP policy can be bypassed to execute attacker-controlled scripts
3
Slide 13
Slide 13 text
Evaluation of CSPs
◉ We only considered automatic & FP-free checks
◉ We assess if CSP can be bypassed (XSS)
◉ Checks:
○ Usage of ’unsafe-inline’ in script-src
○ Missing object-src
○ Use of wildcards in whitelists
■ E.g. script-src * http: https: data:
○ Unsafe origin in whitelists
■ JSONP-like endpoints
■ Endpoints hosting Angular
Slide 14
Slide 14 text
Some CSP Bypass Examples
'unsafe-inline' in script-src
script-src 'self' 'unsafe-inline';
object-src 'none';
CSP-Bypass:
">'>alert(1337)
URL scheme/wildcard in script-src
script-src 'self' https: data: *;
object-src 'none';
CSP-Bypass: ">'>
Missing or lax object-src
script-src 'none';
CSP-Bypass: ">'>
JSONP-like endpoint in whitelist
script-src 'self' whitelisted.com;
object-src 'none';
CSP-Bypass: ">'>
AngularJS library in whitelist
script-src 'self' whitelisted.com;
object-src 'none';
CSP-Bypass: "><script
src="https://whitelisted.com/angularjs/1.1.3/angular.min.js">
These bypasses can be verified in an automated and FP-free manner
Do CSP whitelists work in practice ?
The median policy has 12 distinct whitelisted hosts (in script-src).
At the median of 12 entries, we managed to bypass 94.8 % of all policies!
Slide 18
Slide 18 text
Do CSP whitelists work in practice ?
Top 10 hosts for whitelist
bypasses are sufficient to
bypass 68% of all unique CSPs!
Slide 19
Slide 19 text
CSP-Evaluator
https://csp-evaluator.withgoogle.com
● Core library is open source
● Also as a Chrome Extension
Slide 20
Slide 20 text
Do CSP whitelists work in practice ?
◉ Problems due to 'unsafe-inline', missing object-src,
and wildcards could potentially be fixed
◉ Stop whitelisting domains that allow to bypass CSP
is a much harder problem:
○ Can't use CDNs
○ Can't use widgets (e.g. Google Maps)
○ ...
Slide 21
Slide 21 text
'strict-dynamic'
Drop whitelists and use nonces with dynamic trust propagation instead
5
Slide 22
Slide 22 text
Effects of 'strict-dynamic'
◉ Nonce-only not feasible in practice (libraries,
widgets)
◉ Grant trust transitively via a one-use token (nonce)
instead of listing whitelisted origins
◉ If present in a script-src or default-src directive,
together with a nonce and/or hash
○ discard whitelists (for backward-compatibility)
○ Allow JS execution triggered by non-parser-inserted active
content (dynamically generated).
Slide 23
Slide 23 text
'strict-dynamic' propagates trust to non-parser-inserted JS
var s = document.createElement("script");
s.src = "//example.com/bar.js";
document.body.appendChild(s);
var s = "<script ";
s += "src=//example.com/bar.js>";
document.write(s);
var s = "<script ";
s += "src=//example.com/bar.js>";
document.body.innerHTML = s;
Slide 24
Slide 24 text
How to adopt strict CSP ?
1. Add nonces to elements
2. Refactor inline event handlers and javascript: URIs
3. Serve the following Content-Security-Policy header:
script-src 'nonce-{random}' 'unsafe-inline''strict-dynamic' https: http:;
object-src 'none';
Detailed instructions on https://csp.withgoogle.com
Slide 25
Slide 25 text
Advantages of a strict CSP ?
◉ tags injected via XSS will be blocked, because of
missing nonce
◉ No host/path whitelists necessary!
○ Less breakages
○ No need to go through the painful process of crafting and maintaining a
whitelist → every product uses the same CSP!
◉ No bypasses because of JSONP-like endpoints on external
domains
Slide 26
Slide 26 text
Does it work in practice ?
◉ Yes! 'strict-dynamic' is already served to millions of users
◉ Complex web applications with 'strict-dynamic':
○ Google Photos, Google Cloud Console, Google Wallet, Google History
Chrome Web Store, Google Careers Search...
Slide 27
Slide 27 text
Browser support for CSP
:)
:(
Nonce support
'strict-dynamic' support
CSP support
Slide 28
Slide 28 text
Research Questions
◉ How is CSP used on the web?
◉ Do deployed CSPs protect against XSS?
◉ Do CSP whitelists work in practice?
◉ Is there a better way to effectively mitigate XSS?
No! >94% automatically bypassable
No! Top 10 domains sufficient to bypass 68% CSPs
Mostly to mitigate risk of XSS
Nonces/hashes + 'strict-dynamic'
Slide 29
Slide 29 text
Any questions ?
You can find us at:
{lwe,mikispag,slekies,aaj}@google.com
@we1x, @mikispag, @slekies, @arturjanc
Thanks!
Slide 30
Slide 30 text
Appendix
A
Slide 31
Slide 31 text
Recap: What is XSS?
String error = Request.getParameter("error");
response.write(“
” + error + “
”);
◉ Attacker controlled scripts executing in the context of a user
GET /errorPage?error=alert(1)
alert(1)
Slide 32
Slide 32 text
Most commonly whitelisted domains
Count Origin XSS bypass JSONP bypass Angular bypass 'object-src' bypass
8825 www.google-analytics.com yes, if 'unsafe-eval' yes, if 'unsafe-eval' no no
7201 *.googleapis.com yes yes yes yes
6307 *.google-analytics.com yes, if 'unsafe-eval' yes, if 'unsafe-eval' no no
5817 *.google.com yes yes no no
5475 *.yandex.ru yes yes no no
5146 *.gstatic.com yes no yes no
5076 vk.com yes yes no yes
4728 mc.yandex.ru yes yes no no
4423 yandex.st yes no yes no
4189 ajax.googleapis.com yes yes yes yes
3829 *.googlesyndication.com yes yes no no
3621 *.doubleclick.net yes yes no no
3617 yastatic.net yes no yes no
2959 connect.facebook.net no no no no
2809 www.google.com yes yes no no