{"id":"sec-dev-security-headers-check","audience":"developers","category":"security","track":"security","technique":"constraints","title":"Compare response headers to your security baseline","free":false,"task":"Check these production response headers against your baseline: HSTS with max-age of at least 31536000, a Content-Security-Policy header, X-Content-Type-Options: nosniff, a frame-ancestors or X-Frame-Options rule, and no server version in the Server header. List only what's missing or too weak, numbered in the baseline's order, as 'header: current -> required'. Plain text, under 70 words.","materialLabel":"curl output and notes (attached to your prompt automatically)","material":"$ curl -sI https://shop.example.com/\nHTTP/2 200\ndate: Thu, 06 Nov 2026 14:02:11 GMT\ncontent-type: text/html; charset=utf-8\nserver: nginx/1.18.0\nstrict-transport-security: max-age=86400\nx-frame-options: DENY\ncache-control: no-store\nset-cookie: session=...; Path=/; HttpOnly; Secure; SameSite=Lax\nreferrer-policy: strict-origin-when-cross-origin\npermissions-policy: camera=(), microphone=()\nx-request-id: 7c1e2a9b\n\nNotes:\n- CSP was added on staging last week (Content-Security-Policy: default-src 'self') but hasn't been deployed to production yet.\n- Marketing asked whether we can drop x-frame-options so partners can embed the shop. Not approved.\n- The load balancer adds x-request-id for tracing.","rules":[{"type":"numberedItems","count":4},{"type":"plainText"},{"type":"maxWords","max":70}],"mistakes":[{"title":"Counting staging as live","why":"The AI reads the note about CSP and treats it as deployed.","fix":"Say: \"Judge only the production headers shown.\"","checks":["r0"]},{"title":"Flagging extra headers","why":"The AI suggests improvements to cookies and permissions-policy that your baseline doesn't require.","fix":"Add: \"Only flag what breaks the baseline, in the baseline's order.\"","checks":["r0","r1"]},{"title":"No values","why":"The AI says 'HSTS is weak' without the number to set.","fix":"Show the shape: \"header: current -> required.\"","checks":["r2","numberedItems"]},{"title":"Trusting the AI to count words","why":"AI is bad at counting. Ask for \"under 70 words\" and it often lands well over.","fix":"Ask for less than the limit and cap each line: \"each line under 15 words, under 50 words total.\"","checks":["maxWords"]},{"title":"Letting markdown in","why":"AI adds bold and headings by default, and in the ticket they show up as stray symbols.","fix":"Add: \"Plain text only, no bold, no headings.\"","checks":["plainText"]}],"promptHints":[{"label":"Gives the baseline","patterns":["31536000","nosniff","baseline","csp|content-security"]},{"label":"Uses production only","patterns":["production","live","not staging","only the headers"]},{"label":"Shows the line shape","patterns":["->","current","required"]},{"label":"Sets a word limit","patterns":["\\d+\\s*words","word (limit|count)"]},{"label":"Asks for plain text","patterns":["plain","no bold","no markdown","no formatting","no headings"]}],"hint":"Header scanners and AI both love to flag everything. Give it your baseline, say only production counts, and ask for current and required values.","rubricLabels":["Lists exactly these 4 and nothing else: HSTS max-age=86400 (needs at least 31536000), Content-Security-Policy missing in production, X-Content-Type-Options missing, and server: nginx/1.18.0 showing the version (no lines or comments about x-frame-options, cookies, cache-control or other headers)","The lines are in the baseline's order: HSTS, then Content-Security-Policy, then X-Content-Type-Options, then Server","Each line shows the current value (or 'missing') and the required value or fix (for example 'add nosniff' or 'remove the version')"]}