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

Content Security Policy

722b8ed8e04ba2e0965d55b3035ae315?s=47 Ian Oxley
September 29, 2015

Content Security Policy

My talk at OWASP Newcastle on 29 September 2015 on Content Security Policy.

722b8ed8e04ba2e0965d55b3035ae315?s=128

Ian Oxley

September 29, 2015
Tweet

Transcript

  1. Content Security Policy Ian Oxley, OWASP Newcastle, 29 September 2015

  2. What is Content Security Policy? Policy Directives, CSP Level 1,

    and CSP Level 2 Reporting
  3. selfie with security guards by arileu: https://flic.kr/p/xaoQUS Security is hard

  4. XSS ranked in the top 3 vulnerabilities on the OWASP

    Top 10 since forever * * 2007, 2010, and 2013
  5. Gives the browser a whitelist of trusted sources where content

    can be loaded or executed from Content Security Policy:
  6. Content-Security-Policy: script-src ‘self’; HTTP Header One or more directives

  7. None
  8. Level 1

  9. Level 1 http://caniuse.com/#feat=contentsecuritypolicy

  10. Level 1 style-src default-src media-src script-src object-src font-src img-src connect-src

    frame-src
  11. ‘self’

  12. ‘none’

  13. ‘URL’ * wildcard support

  14. data: https: *://*.example.com:* https://cdn.example.com

  15. <style> .container { margin-top: 2rem; … } </style> <section style=“margin-top:

    1rem;”> … </section> <script> document.documentElement.className = ‘js’; </script> <a href=“javascript:link();”>…</a> <img onclick=“loadPreview()”>
  16. <style> .container { margin-top: 2rem; … } </style> <section style=“margin-top:

    1rem;”> … </section> <script> document.documentElement.className = ‘js’; </script> <a href=“javascript:link();”>…</a> <img onclick=“loadPreview()”> ‘unsafe-inline’
  17. <script> setTimeout(‘console.log(foo);’, 5000); setInterval(‘console.log(foo);’, 5000); </script> <script> eval(‘console.log(“foo”)’); </script> <script>

    var foo = new Function(‘foo’, ‘bar’, ‘return foo + bar’); </script>
  18. <script> setTimeout(‘console.log(foo);’, 5000); setInterval(‘console.log(foo);’, 5000); </script> <script> eval(‘console.log(“foo”)’); </script> <script>

    var foo = new Function(‘foo’, ‘bar’, ‘return foo + bar’); </script> ‘unsafe-eval’
  19. Content-Security-Policy: default-src ‘self’;

  20. Content-Security-Policy: default-src ‘self’ https:;

  21. Content-Security-Policy: default-src ‘self’ https:; script-src https://cdn.example.com

  22. Content-Security-Policy: default-src ‘self’ https:; script-src ‘self’ https: https://cdn.example.com

  23. default-src ‘self’ https:; script-src ‘self’ https: https://cdn.example.com https://ajax.googleapis.com; style-src ‘self’

    https: https://cdn.example.com; Content-Security-Policy:
  24. default-src ‘self’ https:; script-src ‘self’ https: https://cdn.example.com https://ajax.googleapis.com; style-src ‘self’

    https: https://cdn.example.com; object-src ‘none’; Content-Security-Policy:
  25. Level 2

  26. Level 2 http://caniuse.com/#feat=contentsecuritypolicy2

  27. Level 2 style-src default-src media-src script-src object-src font-src img-src connect-src

    frame-src
  28. Level 2 style-src default-src media-src script-src object-src font-src img-src connect-src

    frame-src form-actions base-uri child-src frame-ancestors plugin-types
  29. Content-Security-Policy <meta> <meta http-equiv=“ ” default-src ‘self’ https:; content=“ ”>

  30. Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://example.com ‘nonce-X87di93dkeff’; Using a nonce

  31. <script> console.log( “No nonce attribute - won’t execute”); </script>

  32. <script nonce=“Gdidj89sk28j92pp”> console.log( “Nonce mismatch - won’t execute”); </script>

  33. <script nonce=“X87di93dkeff”> console.log( “Nonce matches - script executes”); </script>

  34. <script nonce=“X87di93dkeff”> src=“//url.com/not-on-whitelist”> </script> // Valid nonce - script executes

  35. Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘sha256-2eXTeAxXc4NfEdtTitmpuNQV 41/dtCeCYiAwxZCvkGo=’; Using a hash

  36. // Script executes - computed hash // matches the one

    in the header // matches the one in the header <script>alert(‘Hello, OWASP.’);</script>
  37. // Neither of these execute - whitespace // and newlines

    cause a different hash // to be computed <script> alert(‘Hello, OWASP.’);</script> <script> alert(‘Hello, OWASP.’); </script>
  38. If you really, absolutely must have inline script and style,

    you can enable it by adding 'unsafe- inline' as an allowed source in a script-src or style-src directive. You can also use a nonce or a hash (see below). But please don’t. Banning inline script is the biggest security win CSP provides, and banning inline style likewise hardens your application. Mike West, An Introduction to Content Security Policy http://www.html5rocks.com/en/tutorials/security/content-security-policy/ “
  39. Reporting

  40. Browser consoles don’t work so well in production

  41. report-uri directive takes a URL as its value. JSON sent

    via HTTP POST for each policy violation.
  42. Content-Security-Policy: default-src ‘self’; script-src ‘self’ http://cdn.example.com; style-src ‘self’ http://cdn.example.com; report-uri

    /csp-report;
  43. Content-Security-Policy-Report-Only: default-src ‘self’ https:; https://cdn.example.com report-uri /csp-report;

  44. Content-Security-Policy: default-src ‘self’; script-src ‘self’ http://cdn.example.com; style-src ‘self’ http://cdn.example.com; report-uri

    /csp-report; Content-Security-Policy-Report-Only: default-src ‘self’ https:; https://cdn.example.com report-uri /csp-report;
  45. CSP whitelists trusted origins using policy directives report-uri can monitor

    CSP in production Although you can enable them, inline styles and scripts are off by default for a reason
  46. any questions? @ianoxley

  47. thanks @ianoxley