Skip to content

HTTP Headers Checker guide

Tool guide. Updated .

What the XGM HTTP Headers Checker reports for HSTS, CSP, X-Frame-Options, Referrer-Policy and more, with ready-to-use fixes for nginx and other servers.

What security headers do

Every HTTP response carries headers that browsers read before rendering the page. A handful of them switch on protections that the browser cannot apply by default without breaking older sites: HTTPS-only access, restrictions on script sources, protection against being framed by another site. Sending them costs almost nothing and closes whole classes of attacks.

Headers are per response. A header set in one server block or application route does not automatically apply to others, and proxies or CDNs can add, change or remove them. That is why checking the real response from outside is more reliable than reading configuration files.

How the checker reads headersXGM requests https://<domain>, follows redirects to the final page, reads the response headers and turns each security header into a finding with a fix.Request https://example.comFrom the XGM server; private and internaltargets are refusedFollow redirectsUp to six hops to the final URLRead the final responseStatus code and every response headerEvaluate security headersHSTS, CSP, X-Content-Type-Options,X-Frame-Options, Referrer-Policy,Permissions-PolicyExtra checksSoftware version leaks and cookie flags
XGM requests https://<domain>, follows redirects to the final page, reads the response headers and turns each security header into a finding with a fix.

How to use the HTTP Headers Checker

  1. Open the HTTP Headers Checker and enter a domain, for example example.com.
  2. XGM requests https://example.com, follows redirects and reads the headers of the final page.
  3. Review the verdict and the finding per header, the CSP analysis (unsafe sources, missing directives, reporting) and the cache headers. Missing or weak headers include a snippet for nginx, Apache, Caddy and Cloudflare you can copy.
  4. Open "All response headers" to see the raw list, including caching and server headers.
  5. After changing your configuration, run the check again; the permalink keeps the domain in the URL. The Full report tab adds a scored header report with recommendations.

Because headers come from the final page, a redirect from example.com to www.example.com means you see the headers of www. Check the bare domain's redirect responses with the Redirect Checker, especially for HSTS, which should also be sent on redirects.

The headers and what the checker expects

Security headers
HeaderPasses whenWhy it matters
Strict-Transport-SecurityPresent with max-age of at least 15552000 (180 days)Browsers use HTTPS only, closing the first-visit HTTP gap
Content-Security-PolicyPresent without 'unsafe-inline' or 'unsafe-eval' in script-src, wildcards, or missing object-srcMain browser defence against injected scripts
X-Content-Type-OptionsnosniffStops browsers from guessing content types
X-Frame-OptionsPresent (DENY or SAMEORIGIN)Prevents clickjacking; frame-ancestors in CSP is the modern equivalent
Referrer-PolicyPresent and not unsafe-urlLimits how much of your URLs is sent to other sites
Permissions-PolicyPresent (optional; missing is informational)Disables browser features such as camera or geolocation
A solid starting set for nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

Start CSP in report-only mode

The CSP line above is a strict default that can break sites with inline scripts or third-party widgets. Roll it out with Content-Security-Policy-Report-Only first, as described in the CSP guide.

Version leaks and cookie flags

Headers such as Server: nginx/1.18.0 or X-Powered-By: PHP/7.4.3 tell anyone which software versions you run. That does not create a vulnerability, but it saves attackers time when a version has known problems. The checker reports version numbers in Server, X-Powered-By and ASP.NET version headers as informational findings.

Hiding version numbers
# nginx
server_tokens off;

# PHP (php.ini)
expose_php = Off

Cookies set by the page are checked for three flags. Secure keeps the cookie off plain HTTP, HttpOnly hides it from JavaScript, which matters for session cookies, and SameSite limits when the browser sends it with cross-site requests. A session cookie without them is easier to steal or misuse.

A well-formed session cookie
Set-Cookie: session=4f9c2b…; Path=/; Secure; HttpOnly; SameSite=Lax

Common mistakes

Why a header you configured is missing
CauseExplanationFix
nginx add_header without alwaysHeaders are skipped on error responsesAdd always
add_header in a location blockIt replaces all headers inherited from the server blockRepeat the headers or use an include file
CDN or proxy overridesThe edge sets its own values or strips headersConfigure headers at one layer and verify from outside
Headers set by the application onlyStatic files and error pages served by the web server lack themSet security headers in the web server or CDN
Duplicate headers with different valuesBrowsers may apply the first or combine themRemove duplicates

The X-XSS-Protection header is sometimes still recommended by old checklists. Modern browsers removed the feature it controlled, and the header is no longer useful; a Content Security Policy replaces it.

Setting headers on other servers and platforms

The nginx snippets in the findings translate directly to other web servers. Set the headers once, at the layer that serves every response, and prefer the web server or CDN over application code so static files and error pages get them too.

Apache httpd (mod_headers)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Caddy
example.com {
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "strict-origin-when-cross-origin"
        -Server
    }
}

CDNs and hosting platforms usually offer a rules or headers section in their dashboard, or a configuration file in the repository, for adding response headers. After changing them, purge cached responses if the platform caches headers along with content, then check again from outside.

Keep a short record of which layer owns each header. When a site moves to a new platform, security headers are among the settings most often lost, because nothing breaks visibly when they disappear. Running the checker after every migration catches that in seconds.

Other headers worth a look

The raw header list also shows caching and performance settings. Cache-Control decides how long browsers and CDNs keep a response, and pages with personal data should use private or no-store. Compression shows up as Content-Encoding: gzip or br, and Vary explains which request headers change the response.

Cross-origin isolation headers (Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy) matter for applications that need powerful browser features or want strict isolation from other sites. They are not required for most websites, so the checker lists them without grading them.

FAQ

Which security headers are most important?

Strict-Transport-Security and Content-Security-Policy give the biggest protection. X-Content-Type-Options and frame protection are easy additions; Referrer-Policy and Permissions-Policy tidy up privacy and features.

Why does the checker show headers from a different URL?

It follows redirects and reports the final page. If example.com redirects to www.example.com, the headers come from www.

Can I set security headers in HTML meta tags?

Only some. CSP can be partly set with a meta tag, but HSTS, X-Frame-Options and frame-ancestors must be HTTP headers.

Is X-Frame-Options still needed with CSP frame-ancestors?

Modern browsers use frame-ancestors when both are present. Sending X-Frame-Options as well is harmless and covers older browsers.

Does a perfect header score make a site secure?

No. Headers reduce the impact of certain attacks in the browser. Application security, patching and access control still matter.

Do headers need to be on every page?

Yes. Browsers apply them per response, and HSTS is refreshed on every response. Set them at the server or CDN so they reach every page, including errors.

Why does my CSP count as weak?

The checker flags 'unsafe-inline' or 'unsafe-eval' in script sources, wildcard sources, a missing default-src or script-src, and a missing object-src. Each allows a way around the protection CSP is meant to give.

Can the checker test pages behind a login?

No. It requests the public URL without cookies. Headers on logged-in pages usually match the public ones if they are set at the server.

Sources