HTTP Security Headers

A Quick Introduction

Adam Hart   ::   Sygnul, LLC   ::   sygnul.com

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

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

Whitelist Cross Origin Resource Sharing (CORS)


Access-Control-Allow-Origin: http://www.example.com/
					

Specify allowed sites rather than using the (*) wildcard

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

Frame Options


X-Frame-Options: deny
					

Prevent your site from being loaded via
<frame> <iframe> or <object>

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.

Preload HSTS


Strict-Transport-Security: max-age=10886400;
	includeSubDomains; preload
					
Preload into browsers at hstspreload.appspot.com
HSTS Preload Site

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.

"Ok, but this all just seems like server configuration stuff"

XSS

"Cross Site Scripting" injection vulnerability


userBio = getUserInfoFromServer()
domElement.innerHTML = "<p>" + userBio + "</p>"
					
(don't do this)

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.

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>"

Script Source


Content-Security-Policy:
	script-src: 'self' 'unsafe-inline' 'unsafe-eval'
					
Allows scripts from our server, inline scripts, and eval() type functions.

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.

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='
					

Links