🛡️ tutorials
The HTTP Security Headers That Actually Matter
By UpNimbus Editorial · Reviewed & edited by Franklin Brown ·July 4, 2026
Headers Are Free Security You Are Probably Not Using
Most websites ship with a handful of response headers set by the framework and nothing more. That is a missed opportunity, because a small set of security headers can shut down entire categories of attack - cross-site scripting, clickjacking, protocol downgrade, MIME sniffing - with a few lines of config and no code changes. Below are the ones worth adding first, what each defends against, and how to set it.
Strict-Transport-Security (HSTS)
HSTS tells browsers to only ever talk to your site over HTTPS, even if a user types http:// or clicks an old link. Without it, an attacker on the network can intercept that first insecure request and downgrade the connection. With it, the browser refuses to connect insecurely at all.
Strict-Transport-Security: max-age=31536000; includeSubDomains
Start with a shorter max-age while you confirm every subdomain serves HTTPS, then raise it to a year. Only add preload once you are certain, because it is hard to undo.
Content-Security-Policy (CSP)
CSP is the most powerful and the most fiddly header. It whitelists where scripts, styles, images, and other resources may load from, which neutralizes most cross-site scripting: an injected <script> from an untrusted origin simply will not execute.
Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self'
A strict policy takes iteration to get right. The common mistake is reaching for 'unsafe-inline' to make things work - which quietly removes most of the protection. Build the policy up from default-src 'self' and add only the specific sources you actually need.
X-Frame-Options
This header controls whether your pages can be embedded in a frame on another site. Blocking that prevents clickjacking, where an attacker overlays your real page inside their own to trick users into clicking things they cannot see.
X-Frame-Options: DENY
Use DENY unless you have a genuine reason to allow framing, in which case SAMEORIGIN permits your own site. Modern setups can express the same intent with CSP’s frame-ancestors, but the header remains widely supported and easy to add.
X-Content-Type-Options
One value, big effect:
X-Content-Type-Options: nosniff
nosniff stops browsers from second-guessing the Content-Type you send. Without it, a file you serve as plain text could be interpreted as executable script under the right conditions. There is no downside to setting it - turn it on everywhere.
Referrer-Policy and Permissions-Policy
Referrer-Policy controls how much of your URL is shared when users click away to another site. strict-origin-when-cross-origin is a sensible default: full URL for same-origin navigation, only the origin for cross-site.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
Permissions-Policy disables powerful browser features you do not use. If your site never needs the camera, microphone, or geolocation, explicitly turning them off means a compromised script cannot silently request them either.
Present Is a Floor, Not a Ceiling
A checklist that shows a header as present confirms coverage, not strength. A weak CSP still counts as “present” while offering a fraction of the protection of a strict one. Use the HTTP Header Inspector to see which of these headers your site sends and grade them at a glance, then review the actual values for the ones that carry the most risk. Fix the missing headers first, tighten the weak ones next, and re-check after each deploy - it is a fast status check away.
Try the tools from this article
Our articles are drafted with AI assistance and reviewed, fact-checked, and edited by a human editor before publishing.