Defeating cross-site scripting
  with Content Security Policy




François Marier – @fmarier
what is a cross-site scripting
    (aka “XSS”) attack?
preventing XSS attacks
print <<<EOF
<html>

<h1>$title</h1>

</html>
EOF;
$title = escape($title);

print <<<EOF
<html>

<h1>$title</h1>

</html>
EOF;
templating system
page.tpl:

 <html>
 <h1>{title}</h1>
 </html>

page.php:

 render(“page.tpl”, $title);
auto-escaping turned ON
page.tpl:

 <html>
 <h1>{title|raw}</h1>
 </html>

page.php:

 render(“page.tpl”, $title);
auto-escaping turned ON




  escaping always ON
the real problem:

browser default = allow all
a way to get the browser
to enforce the restrictions
   you want on your site
$ curl --head http://example.com/


Content-Security-Policy:
  default-src 'self' ;
  img-src     'self' data ;
$ curl --head https://example.com/login


Content-Security-Policy:
  default-src 'self' ;
  img-src     'self' data ;
  frame-src     'self'
     https://login.persona.org ;
  script-src 'self'
     https://login.persona.org
$ curl --head http://fmarier.org/


Content-Security-Policy:
  default-src 'none' ;
  img-src     'self' ;
  style-src 'self' ;
  font-src    'self'
<object>, <applet> & <embed>
                 <script>
             <style> & <link>
                  <img>
   <audio>, <video>, <source> & <track>
           <frame> & <iframe>
                @font-face

WebSocket, EventSource, & XMLHttpRequest
>= 10
what does a CSP-enabled
   website look like?
unless explicitly allowed by your policy

  inline scripts are not executed
unless explicitly allowed by your policy

external resources are not loaded
preparing your website for CSP
   (aka things you can do today)
eliminate inline scripts and styles
<script>
do_stuff();
</script>
<script src=”do_stuff.js”>

</script>
eliminate javascript: URIs
<a href=”javascript:go()”>
Go!
</a>
<a id=”go-button” href=”#”>
Go!
</a>
var button =
  document.getElementById('go-button');
button.onclick = go;
rolling out CSP
start with a loose policy
default-src 'self' *.example.com data;
default-src 'self' *.example.com data;

options unsafe-inline
work towards a stricter policy
default-src 'self';

img-src 'self' static.example.com data;

style-src static.example.com;

script-src static.example.com
use the reporting mode
Content-Security-Policy-Report-Only:
  default-src 'none' ;
  report-uri http://example.com/report.cgi
{

    "csp-report": {

        "document-uri": "http://example.com/page.html",

        "referrer": "http://evil.example.com/haxor.html",

        "blocked-uri": "http://evil.example.com/foo.png",

        "violated-directive": "default-src 'none'",

        "original-policy": "default-src 'none' ... "

    }

}
add headers in web server config
<Location /some/page>

 Header set Content-Security-Policy
   "default-src 'self' ;
    script-src 'self' http://example.org"

</Location>
not a
replacement
 for proper
XSS hygiene
great tool to
 increase the
   depth of
your defenses
Spec:
http://www.w3.org/TR/CSP/




HOWTO:
https://developer.mozilla.org/en/Security/CSP




@fmarier                              http://fmarier.org
100 %
              FREE!


  bonus
HTTP header
wouldn't it be nice if the browser...
...blocked all HTTP requests there?
HTTP Strict
Transport Security
$ curl --head https://login.persona.org

HTTP/1.1 200 OK
Vary: Accept-Encoding,Accept-Language
Cache-Control: public, max-age=0
Content-Type: text/html; charset=utf8
Strict-Transport-Security: max-age= 2592000
Date: Thu, 16 Aug 2012 03:29:19 GMT
ETag: "2943768d6a45793897e83bf8804cd711"
Connection: keep-alive
X-Frame-Options: DENY
Content-Length: 5374
HTTPS only site   turn HSTS on
Spec:
http://www.w3.org/TR/CSP/
https://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec



HOWTO:
https://developer.mozilla.org/en/Security/CSP
https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security




@fmarier                                http://fmarier.org
Photo credits:
Biohazard wallpaper: http://www.flickr.com/photos/rockyx/4273385120/

Under Construction: https://secure.flickr.com/photos/aguichard/6864586905/

Castle walls: https://secure.flickr.com/photos/rdale/585105348/

Wash hands: https://secure.flickr.com/photos/hygienematters/4504612019/




                       Copyright © 2012 François Marier
                       Released under the terms of the Creative Commons
                       Attribution Share Alike 3.0 Unported Licence

Defeating Cross-Site Scripting with Content Security Policy (updated)