Slide 1

Slide 1 text

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

Slide 10

Slide 10 text

Normalize & de-duplicate CSPs CSP Dedupe ◉ Normalization: ○ Parse CSP, ○ Replaced nonces and report URIs, with fixed placeholders, ○ Order directives and directive values script-src 'self' 'nonce-xyz789' example.com; report-uri /csp/a2d0ad39-5d0e-40d4-81ce-e43cb07697b8; script-src 'nonce-abc123' 'self' example.com; report-uri /csp/97830f0f-d1df-4847-b98f-67a28d866731; script-src 'self' 'nonce-PLACEHOLDER' example.com; report-uri PLACEHOLDER; Normalize & de-dupe

Slide 11

Slide 11 text

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

Slide 15

Slide 15 text

Results The state of CSP on the web 4

Slide 16

Slide 16 text

How secure are real-world CSP policies ? Unique CSPs Report Only Bypassable unsafe_inline Missing object_src Wildcard in script-src whitelist Unsafe domain in script-src whitelist Trivially Bypassable Total Unique CSPs 26011 2591 9.96% 21947 84.38% 3131 12.04% 5753 22.12% 19719 75.81% 24637 94.72% XSS Policies 22425 0 0% 19652 87.63% 2109 9.4% 4816 21.48% 17754 79.17% 21232 94.68% Strict XSS Policies 2437 0 0% 0 0% 348 14.28% 0 0% 1015 41.65% 1244 51.05%

Slide 17

Slide 17 text

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