Essential Web Security

Justin Mayer — @jmayer

monitorial.com — @monitorial

Intro

Founder, Monitorial.com

Pelican SSG maintainer

Privacy: I care about it

Overview

Why

The Threat

Just stop

How high are the stakes?

“It’s just a web app”

Passwords over HTTP

Password paste blocking

🎶 Let my passwords go

dom.event.clipboardevents.enabledfalse

No passwords

django-nopassword

https://portier.github.io

Good for business

Hall of Shame

Bank 1

D

Bank 2

D-

Bank 3

D-

Bank 4

F

Health insurance co.

D

Popular e-commerce co.

D

Moral imperative

TLS cert provisioning

Let’s Encrypt:

A Love Story

Authentication methods

Certbot

git clone https://github.com/certbot/certbot

cd certbot; ./certbot-auto

Provisioning

sudo certbot --email name@example.com \
    --domains monitorial.com \
    --text --agree-eula --agree-tos --debug --verbose \
    --must-staple --authenticator standalone auth

https://caddyserver.com

Many other clients

https://letsencrypt.org/docs/client-options/

Free for miscreants, too

Not just TLS: HTTP/2

Configuration management

Ansible, SaltStack, et al

Cipher selection

https://wiki.mozilla.org/Security/Server_Side_TLS

Forward secrecy

Select from pre-defined DH groups:

Auto cipher monitoring

https://statics.tls.security.mozilla.org/server-side-tls-conf.json

HTTP Strict Transport Security (HSTS)

HSTS configuration

# ngx_http_headers_module required | 15768000 seconds = 6 months

add_header  Strict-Transport-Security
    "max-age=15768000; includeSubdomains;";

HSTS pre-loading

https://hstspreload.org

More headers

add_header  X-Frame-Options           SAMEORIGIN;
add_header  X-Content-Type-Options    nosniff;
add_header  X-XSS-Protection          "1; mode=block";

Other easy wins

ssl_session_cache          shared:SSL:5m;
ssl_session_timeout        1h;
ssl_protocols              TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers  on;
ssl_dhparam                /etc/ssl/certs/dhparam.pem;

OCSP stapling

OCSP configuration

ssl_stapling         on;
ssl_stapling_verify  on;
resolver_timeout     5s;
ssl_trusted_certificate /certs/monitorial.com/chain.pem;

OCSP Must-Staple

Content Security Policy

CSP is hard

Whitelist: scripts, CSS, images, fonts, etc

Everything else is blocked

No inline scripts or CSS

“I think for a site of any complexity at all, you need to build for CSP from the very beginning.”

CSP configuration

add_header Content-Security-Policy:
    "default-src 'self';
     script-src https://cdnjs.cloudflare.com:443
                https://secure.gaug.es:443;
     img-src https://i.imgur.com:443";

CSP is hard

Inline scripts and CSS are everywhere

Moving them to external files is laborious

Use Typekit? No CSP for you.

unsafe-inline

Blunt instrument: all or nothing

Can’t apply it to a single domain

Would be nice if CSP were more flexible

https://cspvalidator.org

https://report-uri.io

https://cspisawesome.com

https://cspplayground.com

Subresource Integrity

AMP

All AMP pages must load a script from https://cdn.ampproject.org/

(Don’t use AMP)

tweetbot:///mute/keyword?regex=1&text=
    (%3Fi)(www%5C.)%3Fgoogle%5C.com%5C%2Famp%5C%2F

Generate hashes

wget -qO- FILE.js | \
openssl dgst -sha384 -binary | \
openssl enc -base64 -A

or: https://srihash.org

Tag resources

<script src="https://example.com/example-framework.js"
    integrity="sha384-ECTndYny330R2jlSXBiZkdXzAVi0Z/iDXJTw[...]"
    crossorigin="anonymous"></script>

require-sri-for

Content-Security-Policy: require-sri-for script;
Content-Security-Policy: require-sri-for style;
Content-Security-Policy: require-sri-for script style;

HTTP Public Key Pinning (HPKP)

Protects against CA breach

Someone could impersonate your “secure” site

Root key can generate a certificate for any domain

Backups and fingerprints

openssl genrsa -out site-b1.key 4096
openssl req -new -key site-b1.key -sha256 -out site-b1.csr
openssl genrsa -out site-b2.key 4096
openssl req -new -key site-b2.key -sha256 -out site-b2.csr

openssl x509 -pubkey < site.crt | openssl pkey -pubin \
    -outform der | openssl dgst -sha256 -binary | base64
openssl req -pubkey < site-b1.csr | openssl pkey -pubin \
    -outform der | openssl dgst -sha256 -binary | base64
openssl req -pubkey < site-b2.csr | openssl pkey -pubin \
    -outform der | openssl dgst -sha256 -binary | base64

Web server configuration

add_header Public-Key-Pins \
    'pin-sha256="iv0dWv985sPcJUb9vy6c06iO2FAkQOrJy60wkcWQ4h7="; \
     pin-sha256="Dwc7KK2muQoMjMg5qosU5zLM2N4sjdUFLU1dELDDzSJ="; \
     pin-sha256="UkpY0KkzEsNQC7Yzp8iDSTHarD3BPzlVptNkDPBgODG="; \
     max-age=10';

HPKP and Let’s Encrypt

L.E. re-generates keys on each renewal

Sharp edges

HPKP must be handled with care

Understand it before you deploy it!

Certificate Transparency

Defends against forged certificates

Certificates are submitted to logs

Response: “signed certificate timestamp” (SCT)

Required soon by Chrome/Chromium

Looming deadline: October 2017

SCT Delivery Methods

Let’s Encrypt support coming

Will embed SCTs in certs by October

https://github.com/letsencrypt/boulder/issues/2244

Open Source Tools

On the horizon: TLS 1.3

CAA records

Scrub your logs

https://twitter.com/TechSolidarity

Algo VPN

https://github.com/trailofbits/algo

DNSCrypt

brew install dnscrypt-proxy --with-plugins

# Change DNS resolver to 127.0.0.1

sudo brew services start dnscrypt-proxy

Test via: dnsleaktest.com

Thanks!

justinmayer.com — @jmayer

monitorial.com — @monitorial

SpaceForward
Right, Down, Page DownNext slide
Left, Up, Page UpPrevious slide
POpen presenter console
HToggle this help