Security Tip #2

Content Security Policy HTTP Headers

lightning talk at #parisrb by @DorianLupu

 

slides available online : slides.com/kundigo

July 5th 2016

Content Security Policy (CSP) Headers

Provides a standard method for website owners to declare approved origins of content that browsers should be allowed to load on that website

  • JavaScript,
  • CSS,
  • HTML frames,
  • fonts,
  • images,
  • embeddable objects such as Java applets, ActiveX,
  • audio and video files, and other HTML5 features. 

 

Why use CSP headers

It's a solid safety net against  execution of malicious content in the trusted web page context

  • cross-site scripting (XSS)
  • clickjacking

 

This doesn't mean you can forget about escaping user data on the server side, but if you screw up, CSP will give you a last layer of defense.

 CSP for JS

Content-Security-Policy: script-src 'self' https://apis.google.com

This allows all javascripts file from

  • the current domain
  • apis.google.com domain

 

All other javascript files will be blocked (including inline JS)

Inline Code Considered Harmful

Origin-based whitelisting doesn’t solve the biggest threat posed by XSS attacks: inline script injection.

 

CSP solves this problem by banning inline script entirely: it’s the only way to be sure.

<!-- amazing.html -->
<script>
  function doAmazingThings() {
    alert('YOU ARE AMAZING!');
  }
</script>
<button onclick='doAmazingThings();'>Am I amazing?</button>
// amazing.js
function doAmazingThings() {
  alert('YOU are AMAZING!');
}
document.addEventListener('DOMContentReady', function () {
  document.getElementById('amazing')
          .addEventListener('click', doAmazingThings);
});

Whitelisting Inline Code

<!-- amazing.html -->
<script src='amazing.js'></script>
<button id='amazing'>Am I amazing?</button>
<!-- inline script -->
<script>
  console.log('test)
</script>
<!-- my whitelisted inline script -->
<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  //notice the unique *nonce
  console.log('test)
</script>


# header to whitelists the inline script
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Whitelisting Inline Code (2)

* nonce = number used once

<!-- inline script -->
<script>
  console.log('test)
</script>
# header to whitelists the inline script
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

Whitelisting Inline Code (3)

<!-- inline script -->
<script>
  console.log('test)
</script>
<!-- inline script -->
<script>
  console.log('test)
</script>
# header to whitelists ALL inline script (NOT RECOMMENDED)
Content-Security-Policy: script-src  'unsafe-inline'

Whitelisting Inline Code (4)

<!-- inline script -->
<script>
  console.log('test)
</script>

Other CSP directives

  • connect-src limits the origins to which you can connect (via XHR, WebSockets, and EventSource).
  • font-src specifies the origins that can serve web fonts.
  • form-action lists valid endpoints for submission from <form> tags.
  • img-src defines the origins from which images can be loaded.
  • media-src restricts the origins allowed to deliver video and audio.
  • report-uri specifies a URL where a browser will send reports when a content security policy is violated. This directive cant be used in <meta>tags.
  • style-src is script-src’s counterpart for stylesheets.
  • .... 

Implementing CSP in Rails

Implementing CSP in Rails (2)

#application controller 

before_filter :set_csp

def set_csp
  response.headers['Content-Security-Policy'] = "default-src *; script-src https://assets.example.com; style-src https://assets.example.com"
end

securityheaders.io

tool for checking your security headers

content-security-policy.com

quick reference guide

Questions ?

Thank you

talk at #parisrb by @DorianLupu

slides available online : slides.com/kundigo