Skip to content
PithLab

↑↓ to move · Enter to open · Esc to close

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 & Privacy

Paste 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"
  }
}