Free reference
Security headers and TLS cheat sheet
Headers with the value to send rather than a vague description of it, and the openssl and curl invocations for checking what actually went over the wire.
RESPONSE HEADERS
| Strict-Transport-Security | max-age=31536000; includeSubDomains; preload |
| Content-Security-Policy | default-src 'self'; object-src 'none'; frame-ancestors 'none' |
| X-Content-Type-Options | nosniff |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | geolocation=(), camera=(), microphone=() |
| Cross-Origin-Opener-Policy | same-origin |
| X-Frame-Options | DENY |
| Cache-Control on anything sensitive | no-store |
OPENSSL
| See the handshake and the chain | openssl s_client -connect host:443 -servername host |
| Just the expiry dates | ... </dev/null 2>/dev/null | openssl x509 -noout -dates |
| Read a local certificate | openssl x509 -in cert.pem -noout -text |
| Names the cert actually covers | openssl x509 -in cert.pem -noout -ext subjectAltName |
| The full chain as sent | openssl s_client -connect host:443 -showcerts |
| Do this key and cert match | openssl x509 -noout -modulus -in cert.pem | openssl sha256
openssl rsa -noout -modulus -in key.pem | openssl sha256 |
CURL
curl -sSI https://host headers only | |
curl -sSv https://host -o /dev/null the TLS detail | |
curl --resolve host:443:1.2.3.4 https://host test before DNS moves |
COOKIE FLAGS
Secure | HTTPS only |
HttpOnly | no JavaScript access |
SameSite=Lax | the sane default |
SameSite=Strict | no cross-site at all |
SameSite=None | requires Secure |
WHAT IT USUALLY IS
The browser trusts it, your service does not. Missing intermediate. Serve the full chain.
Works by IP, fails by name. SNI, or the name is not in the SAN.
The parts people get wrong
These are the distinctions that cost real time. They are the reason this sheet exists rather than another list of commands.
Why browsers ignore the certificate Common Name
The Common Name is dead. Browsers read subjectAltName and nothing else. A cert with the right CN and the wrong SAN fails.
HSTS max-age and preload requirements
A max-age under 31536000 is not preload-eligible, and preload is very hard to undo. Be sure before you submit.
Rolling out a Content Security Policy safely
Ship CSP as Content-Security-Policy-Report-Only first. Read the reports for a week. Then enforce.
SameSite=None cookie is not being set
SameSite=None without Secure is dropped silently. No error, no cookie, a very long afternoon.
Security headers on error pages and redirects
A header only protects the response carrying it. Set them on errors and redirects too, not just the happy path.
A certificate error that is not an expired certificate
Certificate expiry is not the usual cause of a certificate error. Chain order and missing intermediates are.
A wildcard certificate expired
A wildcard expired. Check every host that used it, not just the one that paged you.
Certificate works on my machine only
Trusted on your laptop and nowhere else? You installed that CA once and forgot about it.
X-Frame-Options vs CSP frame-ancestors
X-Frame-Options is legacy. CSP frame-ancestors supersedes it, but send both until you are sure nothing old is calling.