HTTP Security Headers
A Quick Introduction
Adam Hart :: Sygnul, LLC :: sygnul.com
Name
"Unreleased, end-to-end encrypted collaboration app"
Want to give brief intro
HTTP Headers
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Content-Type: text/html
Date: Mon, 27 Jul 2015 00:05:46 GMT
Etag: "359670651"
Expires: Mon, 27 Jul 2015 00:05:46 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (ftw/FB85)
X-Cache: HIT
x-ec-custom-error: 1
Content-Length: 1270
Headers from example.com
Every time BROWSER makes request
META DATA associated with the request
like cache control, content length, WHATEVER
a few for SECURITY
Unfortunately BIG topic
Blast through most of these
Internet Explorer Specific
X-Content-Type-Options: nosniff
Prevent IE from "sniffing" files types
X-XSS-Protection: 1; mode=block
Use IE's XSS protection to block suspected attack
START with internet explorer
setting CONTENT TYPE OPTIONS: no sniff
requires correct MIME TYPE
NO PLAIN TEXT to javascript
------
XSS built in
makes sure it's enabled
blocks suspected attacks
Whitelist Cross Origin Resource Sharing (CORS)
Access-Control-Allow-Origin: http://www.example.com/
Specify allowed sites rather than using the (*) wildcard
Won't go deep
if using ACCESS CONTROL ALLOW ORIGIN
If you include this and set it to an asterisk wildcard
lets any site make requests to your site
almost always want to SPECIFY SITES ALLOWED instead
WHITE LIST ALLOWED
or blacklist abusive sites
Cross Site Adobe Plugin Policies
or "Cross Domain Meta Policy"
X-Permitted-Cross-Domain-Policies: master-only
Specify policies for running pdfs or flash across origins
not quite as important
But LOTS of PDFs or Flash
might want this
specify which sites your flash or adobe reader plugins are allowed to request
using a manifest file
Frame Options
X-Frame-Options: deny
Prevent your site from being loaded via <frame> <iframe> or <object>
Frame options
for preventing CLICK JACKING
loads your site inside theirs
WHICH enables certain attacks
STARTS with X-dash
means it's a NON-STANDARD header
eventually be deprecated in favor of another header
HTTP Strict Transport Security
(HSTS) or (STS)
Strict-Transport-Security: max-age=10886400
Strict-Transport-Security: max-age=10886400; includeSubDomains
Force page to run over TLS (SSL/HTTPS). Age in seconds. Optionally include subdomains.
GOOD ONE
Strict Transport Security
sometimes call HSTS or just STS
forces site ENCRYPTED over TLS
subsequent requests MUST USE TLS
ONLY USE if everything on your site works with HTTPS
and you can OPTIONALLY do the same thing for subdomains too
Preload HSTS
Strict-Transport-Security: max-age=10886400;
includeSubDomains; preload
Preload into browsers at hstspreload.appspot.com
Also option PRELOADING HSTS
New versions of BROWSER come Bundled - long list
now browser forwards your site to HTTPS WITHOUT a single network request
SO WHEN visit example.com
browser already interrupts
forwards you to HTTPS example.com
Public Key Pinning
Public-Key-Pins:
pin-sha256="n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=";
pin-sha256="UNhY4JhezH9gQYqvDMWrWH9CwlcKiECVqejMrND2VFw=";
max-age=600
Set the expected TLS certificate. Blocks the site if the certificate given isn't on this list.
SHA-256, base64 encoded SPKI fingerprint. Age in seconds. Requires at least one backup key.
Brand new
No best practices
Python.org only site, using 10 minute max age
BASICALLY: browser EXPECTS certain encryption keys
other keys? BLOCKED
Be EVEN MORE careful
if you revoke your keys AND your backup keys
users can't access your site
"Ok, but this all just seems like server configuration stuff"
maybe zoned out
backend configuration stuff
one last header
requires a lot of thought from a frontend developer
to take advantage
Primarily has to do with...
XSS
"Cross Site Scripting" injection vulnerability
userBio = getUserInfoFromServer()
domElement.innerHTML = "<p>" + userBio + "</p>"
(don't do this)
hopefully cringing
even if the server sanitizes
awful way to show user bio
let's say you havet his on your site
or something less obvious
can reduce the damage of it with CONTENT SECURITY POLICY
Content Security Policy (CSP)
Content-Security-Policy: default none;
script-src 'self' https://ajax.googleapis.com/*;
style-src 'self';
connect-src 'self';
img-src 'self'
Blocks inline script, inline style, eval, and requests to any site not whitelisted.
Content Security policy or CSP
All about whitelisting
You define specific behavior of your site
the browser blocks everything else
Start by seeing what your site uses
Content-Security-Policy-Report-Only: default-src "none"
<meta http-equiv="Content-Security-Policy-Report-Only"
content="default-src 'none'">
*You can also set it via HTML in the <head> using "<meta>"
Start with a header like this
I'm actually using this header on this very site
*OPEN CONSOLE*
At top is a report URI
Handy, it posts a JSON report for each of these violations
If you get a bunch, latest update introduced vulnerability
Or you just need to add something to your whitelist
Most are complaining about localhost
If I add DEFAULT SOURCE SELF - remove most warnings
Script Source
Content-Security-Policy:
script-src: 'self' 'unsafe-inline' 'unsafe-eval'
Allows scripts from our server, inline scripts, and eval() type functions.
SOMEWHERE IN HERE is a warning about inline scripts that I'm using on this page
*CLOSE CONSOLE*
DEFAULT SOURCE SELF won't fix this warning
have to specify unsafe inline
Same thing for EVAL
and other functions that evaluate strings to javascript
Our INNER HTML example would be unable to execute javascript injected into the USER BIO
---
STILL NEED INLINE?
use nonce generated on page load
not worth it
---
Tricky work arounds
So you still have to avoid injection vectors
but MUCH safer
---
*CLOSE CONSOLE*
Other common Sources
Content-Security-Policy:
style-src: 'unsafe-inline' https://ajax.googleapis.com/*;
img-src: data: blob:;
media-src: 'self' mediastream:;
connect-src: https://*.example.com/*
Inline style works like inline scripts. 'self' is for the same domain the page was loaded from. Wildcard (*) allows anything.
*CLOSE CONSOLE*
Inline Styles similar
requires unsafe inline
if blocking inline javascript
inline styles won't execute javascript injections
images created clientside
DATA URL and BLOB URL
media only from our server and mediastreams
websockets and ajax only to example.com
allow any subdomains
Full List of CSP Options
Content-Security-Policy: default-src: 'none';
base-uri: *;
child-src: 'self';
connect-src: 'self' wss://example.com:7443/*;
font-src: 'self';
form-action: 'self';
frame-ancestors: 'none'; //replaces X-Frame-Options: deny
frame-src: 'self';
img-src: data: blob:;
media-src: 'self' mediastream:;
object-src: 'self';
plugin-types: application/pdf;
report-uri: /api/csperror/;
sandbox: allow-popups allow-forms;
script-src: 'self' 'nonce-Nc3n83cnSAd3wc3Sasdfn939hc3';
style-src: 'sha256-UNhY4JhezH9gQYqvDMWrWH9CwlcKiECVqejMrND2VFw='
*CLOSE CONSOLE*
Big list
Some aren't finalized
included in CSP version 2
chrome firefox already implementing
Links
Scan your site's headers:
CSP 2 Spec:
List of useful headers:
This presentation:
That's all the headers
Sites SCAN YOUR PAGE
offers recommendations
HOPE YOU TRY THEM