Skip to content

Security · Beginner · 2 min read

The security headers every site should send

HSTS, X-Content-Type-Options, Referrer-Policy, frame protection and Permissions-Policy — what each response header does and how to set it.

HTTP response headers are instructions a server sends alongside every page. A handful of them are dedicated to security: they tell the browser to refuse insecure connections, stop guessing file types, limit what information leaks to other sites, and prevent your pages being framed by attackers. They cost nothing to add and are among the highest-value, lowest-effort improvements you can make.

Strict-Transport-Security (HSTS)

HSTS tells the browser to only ever contact your site over HTTPS, even if a user types http:// or clicks an old link. Once seen, the browser remembers it for the max-age you specify and upgrades automatically, closing the small window where a first insecure request can be intercepted.

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

X-Content-Type-Options

Browsers sometimes try to "sniff" a response's real type instead of trusting the declared Content-Type. That can turn an uploaded text file into executable script. Setting nosniff disables the guessing.

Example
X-Content-Type-Options: nosniff

Referrer-Policy

The Referer header tells the destination which page a visitor came from — including any path or query string. A sensible policy sends the origin cross-site but never the full URL, so private paths and tokens don't leak.

Example
Referrer-Policy: strict-origin-when-cross-origin

Frame protection

Clickjacking works by loading your site inside an invisible frame on an attacker's page and tricking users into clicking. Deny framing with a Content-Security-Policy frame-ancestors directive (the modern approach), keeping X-Frame-Options as a fallback for older browsers.

Example
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY

Permissions-Policy

Permissions-Policy lets you switch off powerful browser features your site doesn't use — camera, microphone, geolocation — so a compromised script or embedded frame can't quietly request them.

Example
Permissions-Policy: geolocation=(), microphone=(), camera=()

How to fix it

Set these on the server or edge, not per page. On Cloudflare you can add them with a Transform Rule or in a Worker; on nginx use add_header; on Apache use Header set. Add one at a time, deploy, and re-scan to confirm each is present and well-formed.

Glossary

Header
A name/value line the server sends with a response, carrying metadata the browser acts on before rendering.
max-age
How long (in seconds) the browser should remember a directive such as HSTS.
Clickjacking
Tricking a user into clicking something different from what they perceive, usually via a hidden frame.

Luxa checks for this automatically.

Scan your site to see whether this applies to you.