Prerequisites
- Target system, dependencies and environment configured.
Usage
Purpose
Security headers are defence-in-depth: they don't fix vulnerabilities, they shrink the blast radius when one exists. A good CSP turns many XSS bugs into non-events; HSTS closes the downgrade window. This skill covers which headers earn their place, how to check them, and how to set them without breaking the app.
When to use it
During a web assessment (quick win to check) and during hardening. Fair warning: header scanners hand out low-severity findings generously — this skill is about knowing which matter so you don't drown a report in noise.
Procedure
- Pull the response headers and read what's there — and what's missing:
curl -sI https://app.tld | grep -iE 'content-security|strict-transport|x-frame|x-content|referrer|permissions'
- Assess the four that carry real weight first:
- Content-Security-Policy — the big one. Restricts where scripts/resources load from; a strict policy blunts XSS.
- Strict-Transport-Security — forces HTTPS, closing SSL-strip. Needs a long
max-age and, ideally, includeSubDomains; preload.
- X-Frame-Options / CSP frame-ancestors — stops clickjacking by controlling who can frame the page.
- X-Content-Type-Options: nosniff — stops MIME sniffing that turns an upload into script.
- For CSP specifically, judge the content, not just its presence. A policy with
unsafe-inline and unsafe-eval on script-src, or a default-src *, is close to no policy at all.
- Note the ones that are now largely obsolete or misunderstood so you don't over-report them:
X-XSS-Protection is deprecated (turn it off, 0), and Server/X-Powered-By version banners are info leaks worth removing but not vulnerabilities.
- Verify HSTS won't lock users out before recommending
preload — once preloaded, HTTPS is mandatory for the whole domain and reversal is slow.
Cheatsheet
curl -sI https://app.tld
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
X-Frame-Options: DENY # legacy; frame-ancestors in CSP supersedes it
Reading the output
- No CSP, or a CSP with
unsafe-inline/unsafe-eval/wildcards — the meaningful finding. It means an XSS bug gets full impact.
- Missing or short HSTS — users are exposed to downgrade on first/again visits.
max-age under a few months is weak.
- Framing allowed (no
X-Frame-Options and no frame-ancestors) — clickjacking is on the table for sensitive actions.
- Present-but-weak beats absent-and-scary in reports: rank by real risk. A missing
Permissions-Policy is minor; a wildcard CSP is not.
The fix
Set the four load-bearing headers at the edge (reverse proxy or framework middleware) so every response carries them:
- Build the CSP iteratively — start in
Content-Security-Policy-Report-Only mode, collect violation reports, tighten until you can drop unsafe-inline (move inline scripts to files or use nonces/hashes), then enforce.
- HSTS with a two-year
max-age and includeSubDomains; add preload only once you're certain every subdomain does HTTPS.
nosniff and frame-ancestors 'none' (or a tight allowlist) — cheap, no downside for most apps.
- Strip
Server/X-Powered-By version details.
Pitfalls
- CSP set-and-forget. A copied policy with
unsafe-inline gives false comfort. If it doesn't remove inline script, it doesn't stop much XSS.
- HSTS preload regret. Preloading before subdomains support HTTPS locks people out. Confirm coverage first.
- Over-reporting. A wall of "missing header" lows buries the one that matters. Lead with CSP quality and HSTS.
- Headers as a substitute for fixes. They reduce impact; they don't remove the underlying bug. Fix the injection and set the header.
References
- OWASP Secure Headers Project
- OWASP Content Security Policy Cheat Sheet
- MDN — HTTP headers (CSP, Strict-Transport-Security)
Inputs
- Relevant source code, logs, network traces, or system specifications.
Outputs
- Analysis findings, security audit report, or generated code artifacts.
1---2name: security-headers3description: Use when reviewing or hardening a web app's HTTP response headers — CSP, HSTS, and the rest — knowing which actually reduce risk and which are theatre.4---5678## Prerequisites9- Target system, dependencies and environment configured.1011## Usage12### Purpose1314Security headers are defence-in-depth: they don't fix vulnerabilities, they shrink the blast radius when one exists. A good CSP turns many XSS bugs into non-events; HSTS closes the downgrade window. This skill covers which headers earn their place, how to check them, and how to set them without breaking the app.1516### When to use it1718During a web assessment (quick win to check) and during hardening. Fair warning: header scanners hand out low-severity findings generously — this skill is about knowing which matter so you don't drown a report in noise.1920### Procedure21221. Pull the response headers and read what's there — and what's missing:23 ```24 curl -sI https://app.tld | grep -iE 'content-security|strict-transport|x-frame|x-content|referrer|permissions'25 ```262. Assess the four that carry real weight first:27 - **Content-Security-Policy** — the big one. Restricts where scripts/resources load from; a strict policy blunts XSS.28 - **Strict-Transport-Security** — forces HTTPS, closing SSL-strip. Needs a long `max-age` and, ideally, `includeSubDomains; preload`.29 - **X-Frame-Options / CSP frame-ancestors** — stops clickjacking by controlling who can frame the page.30 - **X-Content-Type-Options: nosniff** — stops MIME sniffing that turns an upload into script.313. For CSP specifically, judge the *content*, not just its presence. A policy with `unsafe-inline` and `unsafe-eval` on `script-src`, or a `default-src *`, is close to no policy at all.324. Note the ones that are now largely obsolete or misunderstood so you don't over-report them: `X-XSS-Protection` is deprecated (turn it off, `0`), and `Server`/`X-Powered-By` version banners are info leaks worth removing but not vulnerabilities.335. Verify HSTS won't lock users out before recommending `preload` — once preloaded, HTTPS is mandatory for the whole domain and reversal is slow.3435### Cheatsheet3637```bash38curl -sI https://app.tld3940Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'41Strict-Transport-Security: max-age=63072000; includeSubDomains; preload42X-Content-Type-Options: nosniff43Referrer-Policy: strict-origin-when-cross-origin44Permissions-Policy: geolocation=(), camera=(), microphone=()45X-Frame-Options: DENY # legacy; frame-ancestors in CSP supersedes it46```4748### Reading the output4950- **No CSP, or a CSP with `unsafe-inline`/`unsafe-eval`/wildcards** — the meaningful finding. It means an XSS bug gets full impact.51- **Missing or short HSTS** — users are exposed to downgrade on first/again visits. `max-age` under a few months is weak.52- **Framing allowed** (no `X-Frame-Options` and no `frame-ancestors`) — clickjacking is on the table for sensitive actions.53- **Present-but-weak beats absent-and-scary in reports:** rank by real risk. A missing `Permissions-Policy` is minor; a wildcard CSP is not.5455### The fix5657Set the four load-bearing headers at the edge (reverse proxy or framework middleware) so every response carries them:5859- Build the **CSP** iteratively — start in `Content-Security-Policy-Report-Only` mode, collect violation reports, tighten until you can drop `unsafe-inline` (move inline scripts to files or use nonces/hashes), then enforce.60- **HSTS** with a two-year `max-age` and `includeSubDomains`; add `preload` only once you're certain every subdomain does HTTPS.61- `nosniff` and `frame-ancestors 'none'` (or a tight allowlist) — cheap, no downside for most apps.62- Strip `Server`/`X-Powered-By` version details.6364### Pitfalls6566- **CSP set-and-forget.** A copied policy with `unsafe-inline` gives false comfort. If it doesn't remove inline script, it doesn't stop much XSS.67- **HSTS preload regret.** Preloading before subdomains support HTTPS locks people out. Confirm coverage first.68- **Over-reporting.** A wall of "missing header" lows buries the one that matters. Lead with CSP quality and HSTS.69- **Headers as a substitute for fixes.** They reduce impact; they don't remove the underlying bug. Fix the injection *and* set the header.7071### References7273- OWASP Secure Headers Project74- OWASP Content Security Policy Cheat Sheet75- MDN — HTTP headers (CSP, Strict-Transport-Security)7677## Inputs78- Relevant source code, logs, network traces, or system specifications.7980## Outputs81- Analysis findings, security audit report, or generated code artifacts.