On this page
What Are Security Headers (and How Do You Add Them)?
Security headers like CSP, HSTS, and X-Frame-Options harden a site against common attacks. Learn each header and how to add them.
Quick answer
- Security headers are HTTP response headers that tell the browser to enforce security policies.
- The key ones are Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, and X-Content-Type-Options.
- They’re a one-line-per-header defense that AI-generated apps frequently ship without.
What are security headers?
Security headers are HTTP response headers that instruct the browser to behave more defensively — blocking script injection, forcing HTTPS, preventing clickjacking, and more. They cost almost nothing to add and defend against entire classes of attacks without touching application code. Their absence is a named, recurring gap in AI-generated apps, because assistants rarely add them unless asked.
The essential headers
| Header | What it does |
|---|---|
Content-Security-Policy | Restricts which scripts, styles, and resources the page may load — the main XSS defense |
Strict-Transport-Security | Forces the browser to use HTTPS only (HSTS) |
X-Frame-Options | Stops the page from being framed, preventing clickjacking |
X-Content-Type-Options | Stops MIME-type sniffing (nosniff) |
Referrer-Policy | Controls how much of the URL leaks to other sites |
Permissions-Policy | Restricts browser features like camera or geolocation |
How to add them
The exact method depends on your server. In Express:
app.use((req, res, next) => {
res.setHeader("X-Content-Type-Options", "nosniff");
res.setHeader("X-Frame-Options", "DENY");
res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
next();
});For a static site behind Nginx, add them in the server block:
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000" always;Start with CSP last
Content-Security-Policy is the most powerful but the easiest to get wrong — a strict policy can break your site by blocking legitimate resources. Add the simpler headers first, verify them, then introduce a CSP in report-only mode (Content-Security-Policy-Report-Only) before enforcing it.
How to verify
Check your headers with a scanner like Mozilla Observatory or by reading the response:
curl -I https://your-site.example.comHow to verify it worked: the headers appear in the response and a scanner grades your site’s headers as improved.
Where this bites vibecoders
An AI assistant sets up routing and serving but rarely adds security headers — they’re invisible, and the app “works” without them. The checklist above is the fastest hardening win available: a few lines that close XSS, clickjacking, and downgrade attacks at once. Add them before launch, not after an incident.
Where AI coding assistants get this wrong
- Serving apps with no security headers at all.
- Emitting a CSP with
unsafe-inlineandunsafe-evalthat defeats its own purpose. - Adding HSTS on a site that doesn’t fully support HTTPS, breaking access.
- Copying a header block without testing whether it broke legitimate functionality.
Checklist
- Add
X-Content-Type-Options: nosniffand a strictReferrer-Policyfirst. - Add HSTS once the site is fully on HTTPS.
- Add
X-Frame-Optionsor a CSPframe-ancestorsdirective. - Roll out CSP in report-only mode before enforcing.
- Verify with a header scanner after every change.
FAQ
What is CSP?
Content-Security-Policy tells the browser which sources of scripts, styles, and other resources are allowed. By default-deny’ing inline and unknown scripts, it’s the strongest defense against cross-site scripting, but it must be tuned to your app.
Are security headers enough on their own?
No. They’re one layer of defense in depth. They mitigate specific attack classes (XSS, clickjacking, downgrades) but don’t replace secure code, authentication, or access control.
How do I check my headers?
Use Mozilla Observatory, securityheaders.com, or curl -I. These tools score your headers and explain what’s missing. Checking after deploy should be a routine step.