Get Hacker Buddy

HTTPS and security headers

Hacker's handbook • 3 min read

Encryption and browser security settings are the part of security that visitors never see and attackers always check. They're also the cheapest to get right: most of it is a few lines of server configuration that you set once. This is the short list that matters for a typical site.


Get HTTPS right

  • Redirect everything: every request over plain HTTP should be redirected to HTTPS, on every domain and subdomain you serve.
  • Renew automatically: an expired certificate takes your site down as surely as an outage. Use automatic renewal, and monitor the expiry date anyway in case renewal fails quietly.
  • Turn off old protocol versions: allow TLS 1.2 and 1.3 only. Older versions have known weaknesses and no modern browser needs them.
  • Cover every name: the certificate must be valid for each hostname people use, including the version with and without www.

Tell browsers to insist on HTTPS

A redirect only helps after the first insecure request has been sent. The HSTS header tells a browser to use HTTPS for your site from then on, without asking:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Start with a short max-age while you confirm that every subdomain works over HTTPS, then raise it. Once a browser has seen this header, it will refuse plain HTTP for the whole period.


The headers worth setting

These response headers switch on protections that browsers already have built in:

Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
  • Content-Security-Policy: lists where scripts, styles, and other resources may load from. It's the strongest defence against injected scripts, and the one that takes the most care. Start in report-only mode, see what it would block, then enforce it.
  • X-Content-Type-Options: stops browsers from guessing a file's type, so an uploaded text file can't be run as a script.
  • X-Frame-Options: stops other sites from embedding yours in a frame, which is how clickjacking works. The frame-ancestors directive in a Content-Security-Policy does the same job.
  • Referrer-Policy: limits how much of your page address is sent to other sites when someone follows a link.

Protect your cookies

A session cookie is as good as a password while it's valid. Three flags keep it out of the wrong hands:

Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax
  • Secure: the cookie is only ever sent over HTTPS.
  • HttpOnly: scripts on the page can't read it, so an injected script can't steal the session.
  • SameSite: the cookie isn't sent on requests triggered by other sites, which blocks most cross-site request forgery.

Don't give away more than you need

  • Hide version banners: headers like Server and X-Powered-By often announce exact versions. Removing them doesn't fix anything, but there's no reason to advertise.
  • Be careful with cross-origin access: an Access-Control-Allow-Origin header that allows any site, combined with credentials, lets other websites read your users' data. List the origins you trust instead.
  • Keep error pages plain: stack traces and file paths belong in your logs.

Check what your site really sends

Configuration files say what you intended. The response says what happened:

curl -sI https://yourapp.com

Run it against every hostname you serve, not only the main one. A proxy, a CDN, or a second server can strip or override headers without anyone noticing.


Conclusion

Force HTTPS everywhere, keep certificates renewing, set the four headers, and flag your cookies. None of it takes long, and all of it is visible from the outside, which means attackers can see when it's missing just as easily as you can.


Up next