security-headers-review
A header review that ranks by real risk, rules out obsolete headers, and never proposes a CSP that breaks the site.
Save as .claude/skills/security-headers-review/SKILL.md in a repository, or under ~/.claude/skills/security-headers-review/SKILL.md to have it everywhere. The copy button takes the whole file, frontmatter included.
---
name: security-headers-review
description: Review the HTTP security headers of a live site and report what is missing, misconfigured or obsolete. Use when asked to check security headers, review CSP, HSTS, clickjacking or MIME sniffing protection, harden a site's responses, or explain a header grade.
---
# Security header review
Fetch the real headers with `http_headers` before saying anything. Never assume
a header is present because the framework usually sets it, and never assume it
is absent because you cannot think of a reason for it.
Check the main document URL, not just the origin, and follow redirects to the
final response. Headers frequently differ between a redirect and the page.
## Requires
The toolhq MCP server, for `http_headers` and `ssl_check`:
claude mcp add --transport http toolhq https://toolhq.io/api/mcp
## What to report, in priority order
### 1. HSTS (Strict-Transport-Security)
The highest value header on a site that is already fully HTTPS.
Look for `max-age` and treat anything under 15552000 (180 days) as weak. Note
`includeSubDomains` and `preload` separately.
**The warning that must accompany any recommendation:** HSTS applies to every
subdomain once `includeSubDomains` is set, and it cannot be withdrawn quickly
because browsers cache it for the full max-age. If any subdomain is still HTTP
only, that subdomain becomes unreachable. Never recommend `includeSubDomains`
without asking whether every subdomain is HTTPS, and never recommend `preload`
casually, because removal takes months.
### 2. Content-Security-Policy
The most effective header and the most dangerous to apply.
Report what is present, and specifically whether `script-src` contains
`unsafe-inline` or `unsafe-eval`, because a policy with either provides little
protection against injected script while still appearing to be a policy.
**Do not propose a strict CSP for an existing site as a change to make.** It
will break inline scripts, inline styles, analytics and embeds. The correct
advice is to deploy as `Content-Security-Policy-Report-Only` first, collect
violations, then enforce. Say this every time.
Prefer a nonce or hash based policy over a host allowlist. Note that
`frame-ancestors` supersedes X-Frame-Options.
### 3. X-Content-Type-Options
Should be `nosniff`. No downside, no configuration, no reason to omit it.
Always flag its absence.
### 4. Referrer-Policy
`strict-origin-when-cross-origin` is a sensible default and is what most
browsers now do anyway. Flag `unsafe-url`, which leaks full paths to third
parties, as a real finding.
### 5. X-Frame-Options
Only report this as missing if there is no `frame-ancestors` in a CSP. If
`frame-ancestors` is present, X-Frame-Options is redundant for modern browsers
and its absence is not a finding.
### 6. Permissions-Policy
Worth setting to disable features the site does not use, such as `camera=()`,
`microphone=()`, `geolocation=()`. Low severity. Report as an improvement, not
a fault.
## Obsolete: do not recommend these
- `X-XSS-Protection` — removed from browsers. Recommending it signals the
advice came from an old checklist. Harmless if present; do not ask for it.
- `Expect-CT` — obsolete, certificate transparency is enforced by default.
- `Feature-Policy` — superseded by Permissions-Policy.
- `Public-Key-Pins` — removed, and was actively dangerous.
## Not security headers
Do not pad a report with `X-Powered-By` removal as though it were a control.
Mention version disclosure once, as housekeeping, and do not grade on it.
## Calibrate to the site
A static page and an authenticated application do not need the same report.
- No cookies and no login: CSP and HSTS matter, framing matters less.
- Session cookies: check `Secure`, `HttpOnly` and `SameSite` on `Set-Cookie`,
and treat their absence as higher severity than any missing header.
- A JSON API: CSP is close to irrelevant. Focus on CORS, and specifically on
whether `Access-Control-Allow-Origin` reflects the request origin while
`Allow-Credentials` is true, which is a real vulnerability rather than a
missing nicety.
## Report back
1. Findings ordered by actual risk for this kind of site, not by checklist
order.
2. For each: the current value, why it matters here, and the exact header to
set.
3. Any change that risks breaking the site, flagged, with the safe rollout
path.
4. Obsolete headers explicitly excluded, so the reader knows they were
considered.what it needs
This one looks things up rather than describing them, so it needs live checks. Instructions cannot reach the network on their own, and a skill running through the Claude API has no network access at all. Add the toolhq MCP server and these become real: http_headers, ssl_check.
the instructions, in full
Security header review
Fetch the real headers with http_headers before saying anything. Never assume
a header is present because the framework usually sets it, and never assume it
is absent because you cannot think of a reason for it.
Check the main document URL, not just the origin, and follow redirects to the final response. Headers frequently differ between a redirect and the page.
Requires
The toolhq MCP server, for http_headers and ssl_check:
claude mcp add --transport http toolhq https://toolhq.io/api/mcp
What to report, in priority order
1. HSTS (Strict-Transport-Security)
The highest value header on a site that is already fully HTTPS.
Look for max-age and treat anything under 15552000 (180 days) as weak. Note
includeSubDomains and preload separately.
The warning that must accompany any recommendation: HSTS applies to every
subdomain once includeSubDomains is set, and it cannot be withdrawn quickly
because browsers cache it for the full max-age. If any subdomain is still HTTP
only, that subdomain becomes unreachable. Never recommend includeSubDomains
without asking whether every subdomain is HTTPS, and never recommend preload
casually, because removal takes months.
2. Content-Security-Policy
The most effective header and the most dangerous to apply.
Report what is present, and specifically whether script-src contains
unsafe-inline or unsafe-eval, because a policy with either provides little
protection against injected script while still appearing to be a policy.
Do not propose a strict CSP for an existing site as a change to make. It
will break inline scripts, inline styles, analytics and embeds. The correct
advice is to deploy as Content-Security-Policy-Report-Only first, collect
violations, then enforce. Say this every time.
Prefer a nonce or hash based policy over a host allowlist. Note that
frame-ancestors supersedes X-Frame-Options.
3. X-Content-Type-Options
Should be nosniff. No downside, no configuration, no reason to omit it.
Always flag its absence.
4. Referrer-Policy
strict-origin-when-cross-origin is a sensible default and is what most
browsers now do anyway. Flag unsafe-url, which leaks full paths to third
parties, as a real finding.
5. X-Frame-Options
Only report this as missing if there is no frame-ancestors in a CSP. If
frame-ancestors is present, X-Frame-Options is redundant for modern browsers
and its absence is not a finding.
6. Permissions-Policy
Worth setting to disable features the site does not use, such as camera=(),
microphone=(), geolocation=(). Low severity. Report as an improvement, not
a fault.
Obsolete: do not recommend these
X-XSS-Protection— removed from browsers. Recommending it signals the advice came from an old checklist. Harmless if present; do not ask for it.Expect-CT— obsolete, certificate transparency is enforced by default.Feature-Policy— superseded by Permissions-Policy.Public-Key-Pins— removed, and was actively dangerous.
Not security headers
Do not pad a report with X-Powered-By removal as though it were a control.
Mention version disclosure once, as housekeeping, and do not grade on it.
Calibrate to the site
A static page and an authenticated application do not need the same report.
- No cookies and no login: CSP and HSTS matter, framing matters less.
- Session cookies: check
Secure,HttpOnlyandSameSiteonSet-Cookie, and treat their absence as higher severity than any missing header. - A JSON API: CSP is close to irrelevant. Focus on CORS, and specifically on
whether
Access-Control-Allow-Originreflects the request origin whileAllow-Credentialsis true, which is a real vulnerability rather than a missing nicety.
Report back
- Findings ordered by actual risk for this kind of site, not by checklist order.
- For each: the current value, why it matters here, and the exact header to set.
- Any change that risks breaking the site, flagged, with the safe rollout path.
- Obsolete headers explicitly excluded, so the reader knows they were considered.
check its answers by hand
A skill that reasons well about wrong data is still wrong. For the first few cases, run the same question through a tool that cannot be mistaken.
Grade a site’s HSTS, CSP, X-Frame-Options, and other security headers with a fix note for each.
Open the toolFetch a URL from the server, follow redirects, and inspect response and security headers.
Open the toolwhy it is written this way
A SKILL.md that turns header review into a repeatable pass: which headers matter, which are obsolete, and how to avoid recommending a CSP that breaks the site.
An agent skill for web security header reviews