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

HTTP Security: headers as a shield over your application

HTTP Security: headers as a shield over your application

You are all aware of what are XSS vulnerabilities; do you know what's Clickjacking? You have probably heard of Root Certificate compromission; do you know the principle of a protocol downgrade attack? You're coming to SymfonyCon because you are HTTP application developers and I will present you awesome HTTP headers that will help you to mitigate these kind of attacks, just using W3C WebAppSec recommendations.

Romain Neutron

December 02, 2016
Tweet

More Decks by Romain Neutron

Other Decks in Programming

Transcript

  1. $ curl -I https://github.com 
 HTTP/1.1 200 OK
 Server: GitHub.com


    Date: Mon, 04 Apr 2016 20:10:13 GMT
 Content-Type: text/html; charset=utf-8
 Status: 200 OK
 Cache-Control: no-cache
 Vary: X-PJAX
 X-UA-Compatible: IE=Edge,chrome=1
 Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Fri, 04 Apr 2036 20:10:13 Set-Cookie: _gh_sess=eyJzZXNzaW9uX2lkIjoiYzE1ZjE3NjA4Yjg1MWM3MTk4MjY0ZjdiMzY5ZDJhNzciLC X-Request-Id: 048b988349db27c05f13900c2b8c8dd5
 X-Runtime: 0.011717
 Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
 Public-Key-Pins: max-age=1209600; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB X-Content-Type-Options: nosniff
 X-Frame-Options: deny
 X-XSS-Protection: 1; mode=block
 Vary: Accept-Encoding
 X-Served-By: 7cc969f65c7ec8d9db2fa57dcc51d323
 X-GitHub-Request-Id: 55A8461C:0E34:67919BE:5702CA25 Browsers HTTP Security
  2. $ curl -I https://www.google.fr
 HTTP/1.1 200 OK
 Date: Mon, 04

    Apr 2016 20:09:15 GMT
 Expires: -1
 Cache-Control: private, max-age=0
 Content-Type: text/html; charset=ISO-8859-1
 P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/1 Server: gws
 X-XSS-Protection: 1; mode=block
 X-Frame-Options: SAMEORIGIN
 Set-Cookie: NID=78=qz0a3gQjdiDNPGOR3AAVCO72jOeyaj_EoA8nXeDud6dEqZty2mEdqd9j4gkSNYoqLNM9 iHcHNp7pwr9RQTo0A5id943sj; expires=Tue, 04-Oct
 Alternate-Protocol: 443:quic
 Alt-Svc: quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"
 Transfer-Encoding: chunked
 Accept-Ranges: none
 Vary: Accept-Encoding Browsers HTTP Security
  3. $ curl -I https://www.dropbox.com
 HTTP/1.1 200 OK
 Server: nginx
 Date:

    Mon, 04 Apr 2016 20:10:37 GMT
 Content-Type: text/html; charset=utf-8
 Connection: keep-alive
 x-xss-protection: 1; mode=block
 content-security-policy: img-src https://* data: blob: ; connect-src https://* ws://127 cf.dropb
 x-content-type-options: nosniff
 set-cookie: locale=en; Domain=dropbox.com; expires=Sat, 03 Apr 2021 20:10:37 GMT; Path= set-cookie: gvc=MTYxMzM2OTE1MjU0MzgyMTA2NDI1MzIxMzUyNzc3MDg1ODIzOTA4; expires=Sat, 03 A set-cookie: __Host-js_csrf=VQ1woPFdbo194pKVi50HJuTa; expires=Thu, 04 Apr 2019 20:10:37 set-cookie: t=VQ1woPFdbo194pKVi50HJuTa; Domain=dropbox.com; expires=Thu, 04 Apr 2019 20 set-cookie: puc=; expires=Mon, 04 Apr 2016 20:10:37 GMT; httponly; Path=/; secure
 x-dropbox-request-id: 7772ee5113bda6243af26076c8e25206
 pragma: no-cache
 cache-control: no-cache
 x-dropbox-http-protocol: None
 x-frame-options: SAMEORIGIN
 X-Server-Response-Time: 190
 Strict-Transport-Security: max-age=15552000; includeSubDomains Browsers HTTP Security
  4. X-Xss-Protection • Prevents XSS reflected attacks • Supported by IE8+

    and Chrome • Enabled / disabled • mode-block to completely turn off rendering X-XSS-Protection: 1; mode=block http://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx #BOUTIN
  5. X-Content-Type-Options • Supported by IE and Chrome • "nosniff" only

    supported value X-Content-Type-Options: nosniff https://blogs.msdn.microsoft.com/ie/2008/09/02/ie8-security-part-vi-beta-2-update/
 https://en.wikipedia.org/wiki/Content_sniffing
  6. X-Frame-Options • Supported by Chrome, IE 9, Safari and Firefox

    • Prevents clickjacking X-Frame-Options: DENY X-Frame-Options: SAMEORIGIN X-Frame-Options: ALLOW-FROM https://example.com/
  7. server {
 listen 80;
 
 server_name domain.com;
 add_header x-xss-protection "1;

    mode=block"; add_header x-frame-options "DENY"; add_header x-content-type-options "nosniff"; }
 Browsers HTTP Security
  8. Strict-Transport-Security • RFC-7697 • Supported by Chrome, IE 11, Safari

    and Firefox • Enforce use of HTTPS on your website / Turns any insecure link to secure link • Protects from Protocol Downgrade • Blocks access if no trusted certificate is provided • Only valid after first connection, but can be preloaded Strict-Transport-Security: max-age=expireTime [; includeSubdomains] [; preload] https://tools.ietf.org/html/rfc6797
  9. Strict-Transport-Security server {
 listen 80;
 
 server_name domain.com;
 rewrite ^/(.*)

    https://$host/$1 permanent;
 }
 server {
 listen 443;
 ssl on;
 
 server_name domain.com;
 add_header Strict-Transport-Security “max-age=31536000;"; # ...
 } https://tools.ietf.org/html/rfc6797
  10. Content-Security-Policy • Supported by Chrome, IE 9, Safari and Firefox

    • Prevents XSS • Declare directives about what can be executed on your website Content-Security-Policy: default ‘self’; script-src ‘self’ https://mycdn.com; style-src ‘self’ https://mycdn.com https://www.w3.org/TR/2012/CR-CSP-20121115/
  11. All these directives accept a source list • default-src -

    fallback for any non-declared directive • script-src - <scripts> • style-src - <link rel=“stylesheet"> / @import CSS rule • object-src - <object> / <embed> / <applet> • img-src - <img> sources • media-src - <video> / <audio> / <source> / <track> sources • frame-src - <iframe> / <frame> sources • font-src - @font-face CSS rule • connect-src - XHR open / WebSocket or EventSource constructor https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  12. Source list structure: <directive> source1 source2 … sourceN; Special sources:

    • 'self' : the same origin as the current page (all directives) • 'unsafe-inline' : inline script (script-src and style-src directives) • 'unsafe-eval' : eval / new Function() are disabled / setTimeout and setInterval with non-callable do not work (script-src directive) default-src: 'self'; script-src 'self' https://cdn.domain.com 'unsafe-eval'; https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  13. Content-Security-Policy: 
 default-src 'self'; 
 script-src 'self' https://cdn.domain.com; 
 style-src

    'self' https://cdn.domain.com; https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  14. 'unsafe-eval' Warning: jQuery uses eval when inserting <script> DOM node:

    # does not work
 document
 .getElementsByTagName('body')[0]
 .innerHTML = '<script>console.log("Hello roro")</script>'
 
 # works
 jQuery('body').html('<script>console.log("Hello roro")</script>') https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  15. 'unsafe-inline' What about my inline scripts?
 
 <script>
 window.api_key =

    '{{ api_key }}';
 </script>
 
 <style>
 body {
 background-color: red;
 }
 </style>
 https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  16. Content-Security-Policy: 
 default-src 'self'; 
 script-src 'self' https://cdn.domain.com; 
 style-src

    'self' https://cdn.domain.com; Content-Security-Policy: 
 default-src 'self'; 
 script-src 'self' 'unsafe-eval' 'unsafe-inline' https://cdn.domain.com; 
 style-src 'self' 'unsafe-inline' https://cdn.domain.com; https://www.w3.org/TR/2012/CR-CSP-20121115/ Content-Security-Policy Level 1 - Directives
  17. https://www.w3.org/TR/CSP2/ W3C Recommendation 2014-2015 • New directives • Hashes and

    nonces for inline scripting Content-Security-Policy Level 2
  18. All these directives accept a source list 
 
 •

    base-uri - available document base-urls, no fallback on default-src • child-src - workers and frames. Deprecates frame-src • form-action - <form> actions URLs, no fallback on default-src • frame-ancestors - Is the document embeddable in <frame>, <iframe>, <object>, <applet> or <embed> - related to X-Frame-Options - 'none' is the 'DENY' • plugin-type - mime-types list. <object>, <embed> or <applet> should match the with their type attribute Content-Security-Policy Level 2 - Directives https://www.w3.org/TR/CSP2/
  19. Introduces nonces (random value per request) for inline scripting: #

    HTML
 <script nonce="c89143d4b599538c81058b80a6f975a6">
 window.config.apiKey = 'api-key';
 </script>
 <style nonce="5c5260e3c82f1724a903612c0fc11a0f">
 body { background-color: red; }
 </style> # HTTP header
 Content-Security-Policy: 
 script-src 'self' 'nonce-c89143d4b599538c81058b80a6f975a6';
 style-src 'self' 'nonce-5c5260e3c82f1724a903612c0fc11a0f'; Con: an attacker that can gain access to the nonce can execute whatever script. Content-Security-Policy Level 2 - Nonce https://www.w3.org/TR/CSP2/
  20. Introduces hashes (sha256, sha384 and sha512) for inline scripting: #

    HTML
 <script>
 window.config.apiKey = 'api-key';
 </script> # HTTP header
 Content-Security-Policy: 
 script-src 'self' 'sha256- voRt1IK8+FVdRFaTgn8K6ET46mYOZvT7kYG6Wo3eJNU=' # PHP
 $hash = base64_encode(openssl_digest($scriptContent, 'sha256', true)) Content-Security-Policy Level 2 - Hashes https://www.w3.org/TR/CSP2/
  21. Introduces hashes (sha256, sha384 and sha512) for inline scripting: #

    HTML
 <style>
 body { background-color: red; }
 </style> # HTTP header
 Content-Security-Policy: 
 script-src 'self' 'sha256-xWFKpNfjw6Di/Op4dyVBe876d12Yggw8WSB6ojNM/ bM=' # PHP
 base64_encode(openssl_digest($scriptContent, 'sha256', true)) Content-Security-Policy Level 2 - Hashes https://www.w3.org/TR/CSP2/
  22. In CSP level 2 'unsafe-inline' is not interpreted if the

    a nonce or a hash is contained in the same source list Content-Security-Policy: script-src 'unsafe-inline' 'nonce- c89143d4b599538c81058b80a6f975a6' Is interpreted in CSP level 1 context as: Content-Security-Policy: script-src 'unsafe-inline' Is interpreted in CSP level 2 context as: Content-Security-Policy: script-src 'nonce-c89143d4b599538c81058b80a6f975a6' Content-Security-Policy Level 2 - Support https://www.w3.org/TR/CSP2/
  23. So you can use CSP level 2
 with hashes and

    nonces
 as long as you still include 
 the 'unsafe-inline' directive Chrome, Safari, IE 11, Safari and Firefox https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2
  24. • X-XSS-Protection • X-Content-Type-Options • X-Frame-Options • Strict-Transport-Security • Content-Security-Policy

    • CSP in Real World • End of the world https://www.owasp.org/index.php/List_of_useful_HTTP_headers OWASP useful HTTP headers
  25. Content-Security-Policy
 might be difficult to implement
 in a legacy project

    :( https://www.w3.org/TR/CSP2/ Content-Security-Policy - Project Setup
  26. PHP: composer require nelmio/security-bundle
 Ruby: Twitter Secure Headers csp: enforce:


    default-src:
 - 'self'
 - 'https://%assets_domain%'
 script-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%'
 style-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%' report-uri: [ '/csp/report' ]
 https://github.com/nelmio/NelmioSecurityBundle Content-Security-Policy - Project Setup
  27. PHP: composer require nelmio/security-bundle
 Ruby: Twitter Secure Headers 
 {%

    cspscript %}
 <script>
 window.api_key = '{{ api_key }}';
 </script>
 {% endcspscript %}
 
 {% cspstyle %}
 <style>
 body {
 background-color: red;
 }
 </style>
 {% endcspstyle %} https://github.com/nelmio/NelmioSecurityBundle Content-Security-Policy - Project Setup
  28. PHP: composer require nelmio/security-bundle
 Ruby: Twitter Secure Headers csp: enforce:


    default-src:
 - 'self'
 - 'https://%assets_domain%'
 script-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%'
 style-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%' report-uri: [ '/csp/report' ]
 https://github.com/nelmio/NelmioSecurityBundle Content-Security-Policy - Project Setup
  29. PHP: composer require nelmio/security-bundle
 Ruby: Twitter Secure Headers csp: enforce:


    default-src:
 - 'self'
 - 'https://%assets_domain%'
 script-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%'
 style-src:
 - 'self'
 - 'unsafe-inline'
 - 'https://%assets_domain%' report-uri: [ '/csp/report' ]
 https://github.com/nelmio/NelmioSecurityBundle Content-Security-Policy - Project Setup
  30. Content-Security-Policy-Report-Only • Disable apply directives rules, just collect directives violations

    • Can be used alongside Content-Security-Policy header
 to test a new version Content-Security-Policy-Report-Only: 
 default-src 'self'; report-uri /csp-report-endpoint/ https://www.w3.org/TR/CSP2/ Content-Security-Policy - Project Setup
  31. Content-Security-Policy report-uri • Reports Content Security Policy violations Content-Security-Policy: 


    default-src 'self'; report-uri /csp-report-endpoint/ https://www.w3.org/TR/CSP2/ Content-Security-Policy - Project Setup
  32. {
 'blocked-uri': 'https://m74.dnsqa2016.com',
 'column-number': 290,
 'document-uri': 'https://blackfire.io/',
 'effective-directive': 'script-src',
 'line-number':

    45,
 'original-policy': 'default-src \'self\' https://d2vqbs7xgyce6n.clou 'referrer': 'https://www.google.pl/',
 'source-file': 'https://www.google-analytics.com',
 'status-code': 0,
 'violated-directive': 'script-src \'self\' \'unsafe-inline\' https:/ } https://www.w3.org/TR/CSP2/ Content-Security-Policy report-uri Content-Security-Policy - Project Setup
  33. AngularJS Compatibility • Angular detects CSP usage, but it triggers

    a CSP security exception. • Force angular to behaves in CSP with ng-csp directive (provided natively within angular.js) <body ng-csp>
 <body ng-csp="no-unsafe-eval">
 <body ng-csp="no-inline-style"> https://www.w3.org/TR/CSP2/ Content-Security-Policy - Project Setup
  34. Is my website secured with Content-Security-Policy? • Browser extensions have

    incredible access, you can not do anything about it Browsers HTTP Security
  35. Is my website secured with Content-Security-Policy? • Browser extensions have

    incredible access, you can not do anything about it • You still use trackers (GA) => disable them on sensitive pages Browsers HTTP Security
  36. Is my website secured with Content-Security-Policy? • Browser extensions have

    incredible access, you can not do anything about it • You still use trackers (GA) => disable them on sensitive pages • Your CDN can be compromised Browsers HTTP Security
  37. Is my website secured with Content-Security-Policy? • Browser extensions have

    incredible access, you can not do anything about it • You still use trackers (GA) => disable them on sensitive pages • Your CDN can be compromised Browsers HTTP Security
  38. • X-XSS-Protection • X-Content-Type-Options • X-Frame-Options • Strict-Transport-Security • Content-Security-Policy

    • CSP in Real World • End of the world https://www.owasp.org/index.php/List_of_useful_HTTP_headers OWASP useful HTTP headers
  39. https://www.w3.org/TR/SRI/ http://githubengineering.com/subresource-integrity/ • W3C recommendation from late 2015 • For

    <script> and <link> tags • Support sha256, sha-384 and sha512 message digests • Adds a hash to a resource to check integrity • Server should use CORS as defined by spec (to mitigate brute force attack) <script 
 crossorigin=“anonymous” 
 src="/assets/application.js" 
 integrity="sha256-TvVUHzSfftWg1rcfL6TIJ0XKEGrgLyEq6lEpcmrG9qs="
 ></script> HTTP Security: Subresource Integrity
  40. • X-XSS-Protection • X-Content-Type-Options • X-Frame-Options • Strict-Transport-Security • Content-Security-Policy

    • CSP in Real World • End of the world Subresource Integrity https://www.owasp.org/index.php/List_of_useful_HTTP_headers OWASP useful HTTP headers
  41. • X-XSS-Protection • X-Content-Type-Options • X-Frame-Options • Strict-Transport-Security • Content-Security-Policy

    • CSP in Real World • End of the world Subresource Integrity • Public Key Pinning https://www.owasp.org/index.php/List_of_useful_HTTP_headers
 https://blog.qualys.com/ssllabs/2016/09/06/is-http-public-key-pinning-dead OWASP useful HTTP headers
  42. Resources • https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/ • https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/ • https://blogs.dropbox.com/tech/2015/09/csp-the-unexpected-eval/ • https://blogs.dropbox.com/tech/2015/09/csp-third-party-integrations-and-privilege-separation/ •

    http://githubengineering.com/subresource-integrity/ • https://blog.cloudflare.com/an-introduction-to-javascript-based-ddos/ • http://www.securityweek.com/great-cannon-attack-tool-used-china-censorship-enforcement • https://www.blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf • https://github.com/nelmio/NelmioSecurityBundle • https://www.owasp.org/index.php/List_of_useful_HTTP_headers • https://www.w3.org/TR/SRI/ • https://www.w3.org/TR/CSP2/ • https://www.w3.org/TR/2012/CR-CSP-20121115/ • https://tools.ietf.org/html/rfc6797 • http://caniuse.com/#feat=subresource-integrity • http://caniuse.com/#search=csp • https://blogs.msdn.microsoft.com/ie/2008/09/02/ie8-security-part-vi-beta-2-update/ • https://en.wikipedia.org/wiki/Content_sniffing • https://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x- xss-protection-http-header.aspx • https://blog.qualys.com/ssllabs/2016/09/06/is-http-public-key-pinning-dead