Security Headers Checker API
Grade pasted HTTP response headers (A+ to F) for security: CSP, HSTS, framing, nosniff, Referrer-Policy, Permissions-Policy, cross-origin policies, cookies and information leaks. Nothing is fetched.
POST /api/v1/tools/security-headers-checkerMCP security_headers_checkerSecurity & PrivacyPaste HTTP response headers to grade them A+ to F: HSTS, CSP, framing, cookies, COOP, CORP and version leaks, with fixes for Nginx and Apache. Fetches nothing.
Input
Send these as a JSON object. Unknown fields are rejected.
- headers
- Raw response headers, e.g. the output of curl -I https://example.com or a copy from browser devtools. If several responses are pasted (curl -IL), the last is graded. (string, required)
- server
- Also return a recommended header config for this server: nginx, apache, or none. (string, one of none, nginx, apache, default "none")
curl https://pithlab.com/api/v1/tools/security-headers-checker \n -H "Authorization: Bearer $PITHLAB_KEY" \n -H "Content-Type: application/json" \n -d '{"headers":"HTTP/2 200\ncontent-type: text/html; charset=utf-8\nstrict-transport-security: max-age=31536000; includeSubDomains\nx-content-type-options: nosniff\nx-frame-options: SAMEORIGIN\nreferrer-policy: strict-origin-when-cross-origin\nserver: nginx/1.25.3"}'Example response
{
"ok": true,
"result": {
"grade": "C",
"score": 55,
"findings": [
{
"id": "csp",
"header": "Content-Security-Policy",
"max": 25,
"status": "fail",
"points": 0,
"title": "Missing",
"detail": [
"A Content Security Policy limits where scripts, styles and frames can load from, which blunts cross-site scripting. Start strict and loosen as needed."
]
},
{
"id": "hsts",
"header": "Strict-Transport-Security",
"max": 25,
"status": "pass",
"points": 25,
"title": "Enabled for 365 days",
"detail": [
"includeSubDomains covers every subdomain too.",
"Browsers ignore this header on plain-HTTP responses, so check it on the HTTPS response."
]
},
{
"id": "framing",
"header": "X-Frame-Options / frame-ancestors",
"max": 15,
"status": "pass",
"points": 15,
"title": "X-Frame-Options SAMEORIGIN",
"detail": [
"Blocks framing by other sites. CSP frame-ancestors is the modern replacement and more flexible."
]
},
{
"id": "xcto",
"header": "X-Content-Type-Options",
"max": 10,
"status": "pass",
"points": 10,
"title": "nosniff",
"detail": [
"Browsers will not sniff scripts or styles from the wrong content type."
]
},
{
"id": "referrer",
"header": "Referrer-Policy",
"max": 10,
"status": "pass",
"points": 10,
"title": "strict-origin-when-cross-origin",
"detail": [
"Limits what other sites learn about the page a visitor came from."
]
},
{
"id": "permissions",
"header": "Permissions-Policy",
"max": 5,
"status": "fail",
"points": 0,
"title": "Missing",
"detail": [
"Permissions-Policy switches off browser features you don't use, such as camera=(), microphone=(), geolocation=(), so injected code or embedded frames can't use them."
]
},
{
"id": "coop",
"header": "Cross-Origin-Opener-Policy",
"max": 5,
"status": "fail",
"points": 0,
"title": "Missing",
"detail": [
"COOP: same-origin puts the page in its own browsing context group, so pop-ups and openers from other sites can't reach it (helps against cross-site leaks and Spectre-style attacks)."
]
},
{
"id": "corp",
"header": "Cross-Origin-Resource-Policy",
"max": 5,
"status": "fail",
"points": 0,
"title": "Missing",
"detail": [
"CORP: same-origin (or same-site) stops other sites loading this response with <img>, <script> and similar, which limits data leaks."
]
},
{
"id": "coep",
"header": "Cross-Origin-Embedder-Policy",
"max": 0,
"points": 0,
"status": "info",
"title": "Not set (optional)",
"detail": [
"Only needed for cross-origin isolation (SharedArrayBuffer, high-resolution timers) together with COOP same-origin. It can break third-party embeds, so it is not scored."
]
},
{
"id": "leaks",
"header": "Information leaks",
"status": "warn",
"title": "Version or stack details exposed, 5 points deducted",
"detail": [
"Server: nginx/1.25.3 reveals a version number, which helps attackers match known vulnerabilities. Hide it with server_tokens off in Nginx or ServerTokens Prod in Apache."
],
"points": -5,
"max": 0
}
],
"notes": [],
"status": {
"version": "2",
"code": 200,
"reason": ""
},
"headers": {
"content-type": [
"text/html; charset=utf-8"
],
"strict-transport-security": [
"max-age=31536000; includeSubDomains"
],
"x-content-type-options": [
"nosniff"
],
"x-frame-options": [
"SAMEORIGIN"
],
"referrer-policy": [
"strict-origin-when-cross-origin"
],
"server": [
"nginx/1.25.3"
]
},
"recommended": "Strict-Transport-Security: max-age=31536000; includeSubDomains\nContent-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests\nX-Content-Type-Options: nosniff\nX-Frame-Options: SAMEORIGIN\nReferrer-Policy: strict-origin-when-cross-origin\nPermissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()\nCross-Origin-Opener-Policy: same-origin\nCross-Origin-Resource-Policy: same-origin"
}
}