HSTS, CSP, nosniff, framing, referrers & version leaks

Security headers

Lesson 19 of 20 · 12 min · Module 6: Defence in depth and the capstone

A handful of response headers switch on protections that browsers already have. Checking them is one of the first steps of every security review, and fixing them is usually a one-line change.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Know what each common security header does
  • Read headers without caring about capitals
  • Spot information that helps attackers

The idea

Strict-Transport-Security keeps browsers on HTTPS, Content-Security-Policy limits what a page may load, X-Content-Type-Options: nosniff stops browsers from guessing file types, frame-ancestors (or the older X-Frame-Options) blocks clickjacking, Referrer-Policy limits which addresses are shared with other sites, and Permissions-Policy switches off features such as the camera. Header names ignore capital letters.

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'

01HTTPS, always

After the first visit, Strict-Transport-Security makes the browser use HTTPS for max-age seconds, even when someone types http:// or follows an old link. One year (31536000) is the usual minimum, and preload lists can protect even the first visit.

02Stop framing and guessing

frame-ancestors in the policy, or X-Frame-Options for older browsers, stops other sites from showing your page in an invisible frame and tricking people into clicking it. nosniff stops browsers from running an uploaded text file as a script.

Content-Security-Policy: …; frame-ancestors 'self'
X-Content-Type-Options: nosniff

03Say less about yourself

Server: Apache/2.4.41 or X-Powered-By: PHP/8.1.2 tells attackers exactly which known vulnerabilities to try. Remove them or strip the version numbers. Without a Referrer-Policy, current browsers already use strict-origin-when-cross-origin; unsafe-url would share full addresses with every site.

Your turn

Write auditHeaders(headers) for an object of header names and values, ignoring the capitalisation of names. Return, in this order: hsts-missing, or hsts-short when the HSTS max-age is below 31536000; csp-missing; nosniff-missing unless X-Content-Type-Options is nosniff (any capitalisation); framing-allowed unless the policy contains a frame-ancestors directive or X-Frame-Options is DENY or SAMEORIGIN; referrer-leaks when Referrer-Policy is unsafe-url or no-referrer-when-downgrade; permissions-policy-missing; version-leak when there is an X-Powered-By header or the Server header contains a digit.

What the checks look for

  • Code Temper’s own headers pass
  • Missing headers are found
  • Header names ignore capitals
  • A short HSTS lifetime is reported
  • Either header can stop framing
  • Referrer policies that leak are found
  • Version numbers are spotted
  • The page grades a response
Try it in the editor →

Take this with you

HSTS for a year, a policy with frame-ancestors, nosniff, a careful referrer policy, and no version numbers.

Go a little further

Paste the response headers of a site you use, from the Network panel of the browser’s developer tools, and compare its grade with Code Temper’s.

Learn Web Security Foundations for free

20 short lessons with real code and instant checks.

See the whole course →