HTTP security headers
Grade a site's security headers and get fixes for what's missing.
Have feedback or an idea for this tool?
What are HTTP security headers?
HTTP security headers are response headers a web server sends to instruct the browser how to protect a page. Strict-Transport-Security forces HTTPS, Content-Security-Policy limits where scripts and other resources may load from, X-Frame-Options and X-Content-Type-Options block clickjacking and MIME sniffing, and Referrer-Policy and Permissions-Policy control what the page leaks and which features it may use. This tool fetches a URL, reads the headers it returns, grades what is present, and lists what is missing with the value you should set. Enter a URL to check it. Missing headers are a common and easily fixed gap that vulnerability scans flag. Use it to harden a new deployment, to verify a reverse-proxy or CDN configuration, or to check a site against a recognised baseline such as the OWASP secure headers project before a formal security review.
Key facts
- HTTP security headers are response headers that instruct the browser to enforce defences such as forcing HTTPS, blocking framing, refusing MIME sniffing and constraining which scripts a page may load.
- Strict-Transport-Security (HSTS) forces the browser to use HTTPS and reject downgrades, with a strong value being max-age=31536000; includeSubDomains; preload.
- Content-Security-Policy is the strongest defence against cross-site scripting because it whitelists exactly which origins may serve scripts, styles and other resources and blocks everything else.
- X-Content-Type-Options: nosniff stops the browser from second-guessing the declared Content-Type, and X-Frame-Options: DENY (or the modern CSP frame-ancestors 'none') prevents clickjacking by blocking framing.
- Permissions-Policy switches off powerful browser features a site does not use, such as camera, microphone, geolocation and payment, so an injected script cannot silently reach for them.
What HTTP security headers do
HTTP security headers are response headers a server sends alongside a page that tell the browser to enforce extra defences: force HTTPS, block framing, refuse to guess content types, and constrain what scripts and resources a page may load. They cost nothing to send and shut down whole classes of attack - protocol downgrade, clickjacking, MIME sniffing and cross-site scripting - at the browser rather than in your application code.
This checker fetches the response headers for a URL, reports which protective headers are present and sensibly configured, and grades the result A to F. Missing high-impact headers such as Strict-Transport-Security and Content-Security-Policy pull the grade down the most, because they defend against the most damaging attacks.
The headers are defence in depth, not a substitute for fixing the underlying bug. A good CSP makes an injected script fail to execute, but you still patch the injection point. Treat the grade as a floor to clear, not a finish line.
HSTS, X-Content-Type-Options, X-Frame-Options and Referrer-Policy
Strict-Transport-Security (HSTS) forces the browser to use HTTPS for your domain and refuses any plain-HTTP or invalid-certificate connection, which kills SSL-stripping downgrade attacks. A solid value is 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' - one year, all subdomains, and eligible for the browser preload list. Only enable it once HTTPS works on every subdomain, because it is sticky; start with a short max-age if you are unsure.
X-Content-Type-Options: nosniff stops the browser from second-guessing the declared Content-Type and executing, say, an uploaded text file as JavaScript. It is a one-line header with no downside - always set 'X-Content-Type-Options: nosniff'.
X-Frame-Options: DENY (or SAMEORIGIN) stops other sites embedding your pages in a frame, which is the mechanism behind clickjacking. The modern replacement is the CSP directive 'frame-ancestors', which is more flexible and honoured by current browsers; set 'frame-ancestors 'none'' in your CSP and keep X-Frame-Options for older clients.
Referrer-Policy controls how much of the referring URL is sent when a user clicks away, so you do not leak paths or query strings (tokens, IDs) to third parties. A sensible default is 'Referrer-Policy: strict-origin-when-cross-origin', which sends the full URL within your own origin but only the origin to other sites, and nothing when downgrading HTTPS to HTTP.
Content-Security-Policy: the strongest XSS defence
Content-Security-Policy (CSP) is the single most effective header against cross-site scripting because it whitelists exactly which origins may serve scripts, styles, images, frames and connections, and blocks everything else - so even an injected script fails to run unless it comes from an approved source. Nothing else in this list contains XSS as tightly.
It is also the hardest header to get right. A real policy has many directives, breaks inline scripts and third-party widgets if written carelessly, and a too-loose value (like 'unsafe-inline' or a wildcard) quietly defeats the point. A strong modern approach is nonce- or hash-based: 'Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-<random>'; object-src 'none'; base-uri 'none'; frame-ancestors 'none''. The 'nonce' changes per response and only scripts carrying it execute.
Roll CSP out in stages. Deploy 'Content-Security-Policy-Report-Only' first with a 'report-uri' or 'report-to' endpoint, watch what would have been blocked in real traffic, tighten until the reports are clean, then switch to the enforcing header. Rushing straight to enforce mode usually breaks the site.
MDN: Content-Security-Policy · OWASP: Content Security Policy Cheat Sheet
Permissions-Policy and putting it together
Permissions-Policy (formerly Feature-Policy) lets you switch off powerful browser features your site does not use - camera, microphone, geolocation, USB, payment - so a compromised or injected script cannot silently reach for them. If your app needs none of them, a tight value is 'Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()', where the empty allowlist means 'no origin, including self'.
Set these headers once at the edge or in your server config so they apply to every response: an Nginx 'add_header', an Apache 'Header set', or middleware in your app framework. Send them on error pages and redirects too, not just 200s. Re-scan after any deploy - a config change or a new third-party embed can silently regress a header or force you to loosen your CSP.
If your certificate or TLS setup is the weak link rather than the headers, confirm HTTPS is healthy first with the SSL checker; HSTS is only safe to enable once that is solid.
Glossary
- Strict-Transport-Security (HSTS)
- A response header that forces the browser to use HTTPS for a domain and reject plain-HTTP or invalid-certificate connections, defeating SSL-stripping downgrade attacks. A strong value is max-age=31536000; includeSubDomains; preload, and it should be enabled only after HTTPS works on every subdomain.
- Content-Security-Policy (CSP)
- A header that whitelists exactly which origins may serve scripts, styles and other resources, blocking everything else, which makes it the strongest defence against cross-site scripting. Roll it out first in Content-Security-Policy-Report-Only mode before switching to enforcement.
- X-Frame-Options
- A header (DENY or SAMEORIGIN) that stops other sites embedding a page in a frame, the mechanism behind clickjacking. The modern, more flexible replacement is the CSP frame-ancestors directive, though X-Frame-Options is kept for older clients.
- X-Content-Type-Options
- A header whose nosniff value stops the browser second-guessing the declared Content-Type and, for example, executing an uploaded text file as JavaScript. It is a one-line header with no downside and should always be set.
- Referrer-Policy
- A header controlling how much of the referring URL is sent when a user navigates away, preventing leakage of paths or query strings such as tokens to third parties. A sensible default is strict-origin-when-cross-origin.
- Permissions-Policy
- A header (formerly Feature-Policy) that switches off powerful browser features a site does not use, such as camera, microphone, geolocation and payment, so an injected script cannot silently reach for them. An empty allowlist like camera=() denies the feature to every origin including the site itself.
Questions, answered.
Which security headers do you check?+
The key HTTP response headers: Strict-Transport-Security (HSTS), Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Each defends against a specific class of attack - downgrade, XSS, clickjacking, MIME sniffing and referrer leakage - and the checker reports which are present and sensibly set.
How is the A to F grade worked out?+
The scan scores which protective headers are present and correctly configured, then maps that to a letter grade. Missing high-impact headers like HSTS and Content-Security-Policy pull the grade down the most, while a weak value - such as a CSP using unsafe-inline - counts as present but not effective.
What is HSTS and what value should I use?+
Strict-Transport-Security tells browsers to only ever connect over HTTPS and reject downgrades. A strong value is 'max-age=31536000; includeSubDomains; preload' (one year, all subdomains, preload-eligible). Enable it only after HTTPS works on every subdomain, because it is sticky; start with a short max-age if you are unsure, then raise it.
Why is Content-Security-Policy the most important header?+
CSP whitelists exactly which origins may load scripts, styles and other resources and blocks everything else, so an injected script simply does not run unless it comes from an approved source. That makes it the strongest defence against cross-site scripting - no other header contains XSS as tightly.
Why is CSP the hardest header to get right?+
A real policy has many directives and can break inline scripts or third-party widgets, while a too-loose value like unsafe-inline or a wildcard quietly defeats the point. The safe path is to deploy Content-Security-Policy-Report-Only with a reporting endpoint, watch what would break in real traffic, tighten until reports are clean, then switch to enforce mode.
What is the difference between X-Frame-Options and CSP frame-ancestors?+
Both stop your pages being embedded in a frame to prevent clickjacking. X-Frame-Options (DENY or SAMEORIGIN) is the older header; the CSP directive frame-ancestors is the modern, more flexible replacement honoured by current browsers. Set frame-ancestors 'none' in your CSP and keep X-Frame-Options as well for older clients.
Where do I set these headers?+
Set them once at the edge or in server config so they apply to every response - an Nginx add_header, an Apache Header set, a CDN rule, or middleware in your framework. Make sure they also go out on redirects and error pages, not only on 200 responses.
Are security headers enough to secure my site?+
No. They are an important layer of defence in depth but not the whole job. Pair them with a valid TLS certificate (check it with the SSL checker), keep your server and dependencies patched, and fix the underlying bugs - a header makes exploitation harder, it does not remove the vulnerability.
Is the URL I scan stored?+
No. The scan runs on ServerCake's servers to fetch the target's response headers, and we do not keep a record of the URLs you check.
Cloud that speaks India.
These tools run on ServerCake infrastructure in India. When our cloud opens, you get VMs and managed databases priced in ₹, billed with GST, on India-resident infrastructure. Reserve your spot for early access.
Reserve your spot