How to Audit Your HTTP Security Headers and Fix What Is Missing
Most web application security vulnerabilities get the headlines: SQL injection, XSS, CSRF, misconfigured authentication. HTTP security headers rarely come up in those conversations, yet they are among the fastest wins available to any developer or sysadmin. A single header can block a whole class of attacks, requires zero application code changes, and takes minutes to deploy.
The problem is that most teams do not know which headers they have, which they are missing, or what the headers they do have are actually configured to do. A server that returns X-Frame-Options: SAMEORIGIN looks secure until you realize CSP's frame-ancestors directive supersedes it in every modern browser, and your CSP is either absent or set to unsafe-inline. Worse, header configuration is platform-specific: the same application deployed on nginx, Apache, Express, and a CDN edge function requires a different fix for each layer, and changes at one layer can silently be overridden by another.
This guide covers the eight header categories that matter most, how to check your current configuration, and how to interpret the grades that tell you where you are exposed.
Why HTTP Security Headers Matter
HTTP response headers are instructions your server sends to the browser alongside every page response. Most headers control behavior like caching, compression, and content types. Security headers specifically tell the browser how to handle your page's trust boundaries: what scripts can run, where requests can go, whether the page can be embedded in an iframe, and how cookies should be protected.
The OWASP Secure Headers Project maintains the canonical list of security headers and their recommended values. Their guidance is updated regularly as browser support evolves and new attack patterns emerge. What makes headers particularly valuable from a security standpoint is that they operate at the protocol layer, before any JavaScript or application logic runs. An attacker who finds a way to inject a script tag into your HTML still cannot execute it if your CSP is configured correctly, because the browser will refuse to run scripts from unapproved sources regardless of what is in the HTML.
The cost of getting these wrong is not theoretical. The Verizon DBIR consistently shows that web application attacks account for a large share of breaches, and many successful attacks exploit gaps that headers would have blocked. Clickjacking, cross-site scripting, mixed content injection, and MIME type confusion are all attackable because browsers trust whatever the server sends by default.
The Eight Categories That Get Graded
Security header audits typically break down along these lines:
Content Security Policy (CSP) - controls which scripts, styles, fonts, images, and connections are permitted. A well-configured CSP eliminates most XSS attack surface. An absent or poorly configured CSP is one of the most common findings in any security audit.
HTTP Strict Transport Security (HSTS) - instructs browsers to only connect over HTTPS for a specified period. Blocks SSL stripping attacks and mixed content downgrades.
X-Frame-Options - prevents your pages from being loaded inside iframes on other sites, blocking clickjacking. Largely superseded by CSP's frame-ancestors, but still worth setting for legacy browser compatibility.
X-Content-Type-Options - setting nosniff prevents browsers from MIME-sniffing a response away from the declared content type, blocking attacks that rely on browsers treating files as executable that should not be.
Referrer-Policy - controls how much referrer information is sent when a user navigates from your site. Relevant for both privacy and for leaking sensitive URL parameters to third parties.
Permissions-Policy - limits which browser features (camera, microphone, geolocation, payment, etc.) the page and any embedded content can request. Formerly called Feature-Policy.
Cookie flags - specifically Secure, HttpOnly, and SameSite. These are not headers in isolation but are graded as part of a security header review because improperly flagged cookies are a frequent source of session hijacking and CSRF vulnerabilities.
Additional headers - including Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy, and Cross-Origin-Embedder-Policy, which together control cross-origin isolation and matter significantly for pages using SharedArrayBuffer or precise timer APIs.
How to Check Your Current Headers
The fastest way to see your actual headers is via curl:
curl -I https://yourdomain.com
This returns the response headers without the body. But raw header output tells you what is present, not whether the configuration is correct. A CSP of default-src * is present but provides no protection.
A more useful approach is to run your headers through a grader that checks both presence and configuration quality.
The HTTP Security Header Grader at EvvyTools accepts pasted header output and returns A-F grades across all eight categories. It checks not just whether each header exists but whether its values align with current security recommendations. A CSP with unsafe-inline in the script-src directive gets a lower grade than one using nonces or hashes, even though both headers are technically "present."
"HTTP security headers are some of the lowest-effort, highest-return security improvements we make when auditing a client site. Paste the response headers into a grader, fix what fails, and you have addressed a whole category of browser-level attacks before writing a single line of application code." - Dennis Traina, 137Foundry
Reading the Grades
An A grade on a category means the header is present and configured to current best-practice standards. A B or C means the header is present but with weaker settings than recommended. D or F means the header is absent or so misconfigured that it provides no meaningful protection.
Pay attention to which categories score low. A missing HSTS on a domain that already uses HTTPS everywhere is a lower-severity finding than a missing CSP on a page that loads third-party JavaScript. Context matters when prioritizing fixes.
Common Misconfigurations and How to Fix Them
CSP Too Permissive
The most common CSP failure is a directive that includes unsafe-inline for scripts. This cancels most of the XSS protection CSP is designed to provide, because it allows any inline <script> block to execute.
The fix requires either moving inline scripts to external files, or implementing CSP nonces (a per-request random token added to both the header and each allowed script tag). The MDN Content Security Policy guide covers nonce implementation in detail.
HSTS Missing includeSubDomains
An HSTS header without includeSubDomains leaves your subdomains vulnerable to SSL stripping even if your main domain is protected. The recommended policy is:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
The preload directive submits your domain to browser preload lists, meaning browsers will enforce HTTPS before they have ever seen your HSTS header. This requires submitting to the HSTS preload list separately.
Cookies Missing SameSite
Cookies without a SameSite attribute default to SameSite=Lax in modern browsers, but this behavior is not consistent across all clients, and older browser versions still treat the attribute as absent when unset. Explicitly setting SameSite=Strict on session cookies eliminates cross-site request forgery for those cookies because the browser will refuse to send them on any request originating from a different site. Setting it to None (required for cross-site contexts like embedded payment flows or OAuth callbacks) must be paired with the Secure flag or modern browsers will reject the cookie entirely. Review the MDN SameSite attribute documentation for a precise breakdown of when each value applies.
Referrer-Policy Too Broad
Referrer-Policy: no-referrer-when-downgrade is the browser default but leaks the full URL (including query parameters) to any same-protocol destination. If your app puts session tokens, user IDs, or filters in URLs, a policy of strict-origin-when-cross-origin or no-referrer for sensitive pages is more appropriate. This is particularly relevant for analytics integrations and affiliate tracking, where third-party pixels and scripts may collect referrer data you did not intend to share. Setting the policy at the header level applies it globally, so you do not need to add referrerpolicy attributes to every link on the page.
Related Tools and Resources
Additional EvvyTools dev utilities: - Robots.txt Generator for controlling crawler access alongside your security configuration - Meta Tag Generator for the full set of HTML head meta tags that complement your header configuration
External references: - OWASP HTTP Security Response Headers Cheat Sheet - the most comprehensive single reference for header recommendations and configuration examples - Mozilla Observatory - a free online scanner that grades your headers with detailed remediation guidance - securityheaders.com - another fast header scanner with A-F grades and header explanations - web.dev Security Headers guide - Google's practical guide to implementing each header type
A One-Hour Audit Pays for Itself
Run your headers through a grader today and look at the F-grade categories first. For most applications, fixing the top two or three findings takes under an hour: add a CSP, set HSTS with includeSubDomains, set all session cookies to HttpOnly; Secure; SameSite=Strict. Then re-run the grader to confirm your changes were actually applied at the right layer. It is common to add a header in nginx only to discover a CDN or load balancer is stripping it before it reaches the browser.
The HTTP Security Header Grader shows you exactly what is missing and what each configuration value does. That is a faster starting point than reading through five separate specification documents, and it gives you a before-and-after score to verify your changes actually worked.
Security headers are not a substitute for application-level security. But they are the configuration layer that makes the attacker's job harder before any application code runs, and they are some of the cheapest security improvements available to any web team.