Chapter 6 of 8 · 4 checks · 2 min
Security headers and configuration (A02)
Security misconfiguration is number two in 2025. Headers, TLS and production settings are cheap to fix and easy to check from outside.
Enforce HTTPS everywhere with HSTSMust
Why it matters and how to check
Redirect all HTTP to HTTPS and send
Strict-Transport-Securityso browsers never try plain HTTP again. The OWASP headers cheat sheet givesmax-age=63072000; includeSubDomains; preload. Only addpreloadonce every subdomain serves HTTPS, because a mistake locks users out for the whole max-age.To verify, request
http://versions of your main pages and confirm a redirect to HTTPS. Then read the HSTS header on the HTTPS response. An online TLS scanner should show no old protocol versions and a valid certificate chain.Example
Shell curl -sI https://your.app | grep -i strict-transport-securitySend the baseline security headers on every responseShould
Why it matters and how to check
The headers cheat sheet recommends
X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin, CSPframe-ancestors(orX-Frame-Options: DENYas a fallback) against clickjacking, and aPermissions-Policythat turns off features you do not use. It also says to leaveX-XSS-Protectionoff or set it to 0.To verify, run
curl -sIagainst a page, an API route and a static file, and check each header is present on all three. Headers set only on HTML pages often miss APIs and file downloads.Example
HTTP X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Content-Security-Policy: frame-ancestors 'none' Permissions-Policy: geolocation=(), camera=(), microphone=()Turn off debug modes, default accounts and directory listingsMust
Why it matters and how to check
Debug pages, sample apps, default admin passwords and open directory listings are textbook misconfigurations. They leak stack traces, source paths and sometimes environment variables.
To verify, request a URL that does not exist and one that throws, and confirm the response is a plain error page without a stack trace or framework banner. Try
/.env,/.git/configand common admin paths for your stack: all should return 404. Check that no seeded test or default accounts exist in the production database.