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

Sécurité & HTTP @ Symfony Live Paris 2016

Sécurité & HTTP @ Symfony Live Paris 2016

Si autrefois nous ne nous soucions guère de la sécurité dans nos applications, il serait aujourd'hui impensable de se lancer dans le développement d'une application sans prendre en compte la sécurité vis à vis d'HTTP.

Sans parler des outils communément utilisés dans Symfony (csrf_token, auto escaping Twig, escaping de commandes, hashage de données...), cette présentation s'attachera à présenter les différentes possibilités (CSP, HSTS, Framing options, etc...) offertes par les navigateurs et qu'il est facile a mettre en oeuvre dans Symfony via des bundles ou de la configuration pour éliminer de nombreux vecteurs d'attaque comme les DNS, le CDN poisoning ou les XSS.

https://joind.in/talk/b01cc

Romain Neutron

April 08, 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 -0000; secure; HttpOn Set-Cookie: _gh_sess=eyJzZXNzaW9uX2lkIjoiYzE1ZjE3NjA4Yjg1MWM3MTk4MjY0ZjdiMzY5ZDJhNzciLCJfY3NyZl
 X-Request-Id: 048b988349db27c05f13900c2b8c8dd5
 X-Runtime: 0.011717
 Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; child-sr
 Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
 Public-Key-Pins: max-age=1209600; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";e2gyHMrW5Q06LspMn 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 Sécurité & HTTP
  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/151657?hl=en for more i Server: gws
 X-XSS-Protection: 1; mode=block
 X-Frame-Options: SAMEORIGIN
 Set-Cookie: NID=78=qz0a3gQjdiDNPGOR3AAVCO72jOeyaj_EoA8nXeDud6dEqZty2mEdqd9j4gkSNYoqLNM9PyMu_7SgGDEv5lVxn24zII 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 Sécurité & HTTP
  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.0.0.1:*/ws ; media-sr x-content-type-options: nosniff
 set-cookie: locale=en; Domain=dropbox.com; expires=Sat, 03 Apr 2021 20:10:37 GMT; Path=/; secure
 set-cookie: gvc=MTYxMzM2OTE1MjU0MzgyMTA2NDI1MzIxMzUyNzc3MDg1ODIzOTA4; expires=Sat, 03 Apr 2021 20:10:37 GMT; set-cookie: __Host-js_csrf=VQ1woPFdbo194pKVi50HJuTa; expires=Thu, 04 Apr 2019 20:10:37 GMT; Path=/; secure
 set-cookie: t=VQ1woPFdbo194pKVi50HJuTa; Domain=dropbox.com; expires=Thu, 04 Apr 2019 20:10:37 GMT; httponly; 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 Sécurité & HTTP
  4. X-Xss-Protection • Prevent 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
  5. X-Xss-Protection • Prevent 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
  6. 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
  7. X-Frame-Options • Supported by Chrome, IE 9, Safari and Firefox

    • Prevents clickjacking • Watch Alain’s talk --> X-Frame-Options: SAMEORIGIN
  8. Sécurité & HTTP 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"; }

  9. 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
  10. 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
  11. 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/
  12. 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
  13. Source list structure: <directive> source1 source2 … sourceN; Special sources:

    • 'self' : the same origin as the current page (all directives) • 'unsafe-line' : 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
  14. 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
  15. '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
  16. '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
  17. 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
  18. https://www.w3.org/TR/CSP2/ W3C Recommendation 2014-2015 • New directives • Hashes and

    nonces for inline scripting Content-Security-Policy Level 2
  19. 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 https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2 - Directives
  20. 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. https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2 - Nonce
  21. 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)) https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2 - Hashes
  22. 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)) https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2 - Hashes
  23. In CSP level 2 'unsafe-inline' is not considered 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' https://www.w3.org/TR/CSP2/ Content-Security-Policy Level 2 - Support
  24. 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
  25. • 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
  26. Content-Security-Policy
 might be difficult to implement
 in a legacy project

    :( https://www.w3.org/TR/CSP2/ Content-Security-Policy - Project Setup
  27. composer require nelmio/security-bundle 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
  28. composer require nelmio/security-bundle 
 {% 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
  29. composer require nelmio/security-bundle 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. composer require nelmio/security-bundle 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
  31. Content-Security-Policy-Report-Only • Don't apply the 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
  32. 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
  33. {
 '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.cloudfront.n', 'referrer': 'https://www.google.pl/',
 'source-file': 'https://www.google-analytics.com',
 'status-code': 0,
 'violated-directive': 'script-src \'self\' \'unsafe-inline\' https://www.gstat } https://www.w3.org/TR/CSP2/ Content-Security-Policy report-uri Content-Security-Policy - Project Setup
  34. 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
  35. Sécurité & HTTP Is my website secured with Content-Security-Policy? •

    Browser extensions have incredible access, you can not do anything about it
  36. Sécurité & HTTP 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
  37. Sécurité & HTTP 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
  38. Sécurité & HTTP 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
  39. • 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
  40. 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> Sécurité & HTTP: Subresource Integrity
  41. https://www.owasp.org/index.php/List_of_useful_HTTP_headers • 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 OWASP useful HTTP headers
  42. • 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 OWASP useful HTTP headers
  43. 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