Security Headers Checker

Analyze any website's HTTP security headers, get a security score, and receive specific recommendations — the security headers audit tool built for IT admins, developers, and MSPs.

What are HTTP security headers?

HTTP security headers are response headers sent by a web server that instruct the browser how to behave when handling a page. They are part of the HTTP response — the same layer as Content-Type and Cache-Control — and require no changes to your HTML, CSS, or JavaScript.

Security headers defend against a range of browser-level attacks: cross-site scripting (XSS), clickjacking, protocol downgrade, MIME-type confusion, and cross-origin information leaks. They are one of the highest-leverage security improvements you can make because a single server configuration change protects every user and every page on the site.

For MSPs: Security headers are frequently checked during security audits, penetration tests, and compliance reviews (PCI DSS, SOC 2, ISO 27001). Running this tool against client sites before an audit can identify and fix gaps in under an hour. Most headers take five minutes to add once you know what to set.

Critical headers (scored)

  • Content-Security-Policy — Restricts resource loading. Primary XSS defence. (-25 if missing)
  • Strict-Transport-Security — Forces HTTPS. Prevents SSL stripping. (-20 if missing)
  • X-Frame-Options — Prevents clickjacking via iframe embedding. (-10 if missing)
  • X-Content-Type-Options — Stops MIME-type sniffing attacks. (-10 if missing)
  • Referrer-Policy — Controls referrer header data leakage. (-10 if missing)

Additional headers (scored)

  • Permissions-Policy — Controls access to camera, mic, and other browser APIs. (-5 if missing)
  • Cross-Origin-Opener-Policy — Isolates browsing context from cross-origin windows. (-5 if missing)
  • Cross-Origin-Embedder-Policy — Enables cross-origin isolation for performance APIs. (-5 if missing)
  • Cross-Origin-Resource-Policy — Prevents cross-origin loading of resources. (-5 if missing)
  • X-XSS-Protection — Legacy Internet Explorer filter (informational only, not scored).

Why Content Security Policy matters

Content Security Policy (CSP) is the browser's most powerful XSS defence. Without it, any JavaScript injected into your page through an XSS vulnerability runs with full access to the DOM, cookies, localStorage, and any data the user can see. With a CSP, the browser only executes scripts from sources you explicitly allow.

CSP is delivered as a response header: Content-Security-Policy: default-src 'self'. This single directive tells the browser to only load resources from the same origin. You can then refine it per resource type — for example, allowing Google Fonts (style-src 'self' fonts.googleapis.com) while keeping scripts locked down.

Key CSP directives

  • default-src — Fallback for all resource types not otherwise specified.
  • script-src — Controls which scripts may execute. This is the most critical directive.
  • style-src — Controls which stylesheets may be applied.
  • img-src — Controls image loading sources.
  • connect-src — Controls fetch(), XMLHttpRequest, and WebSocket endpoints.
  • frame-ancestors — Supersedes X-Frame-Options. Controls who can embed this page.

CSP keywords to avoid

  • 'unsafe-inline' — Allows inline scripts and styles. Defeats most XSS protection. Use nonces or hashes instead.
  • 'unsafe-eval' — Allows eval() and similar dynamic code execution. Remove this if you can avoid eval().
  • 'unsafe-hashes' — Less dangerous than unsafe-inline, but still loosens protection.
  • data: — Allows data: URI resources. Can be exploited for script injection.
  • * (wildcard) — Allows any source. Defeats the purpose of CSP.

Why HSTS matters and how to configure it

HSTS (HTTP Strict Transport Security) is a policy that tells browsers to always use HTTPS when connecting to your domain — even if the user types http:// or clicks an HTTP link. Without HSTS, an attacker on the same network can intercept the initial HTTP request before the HTTPS redirect occurs — a technique called SSL stripping.

HSTS works by having the server send: Strict-Transport-Security: max-age=31536000; includeSubDomains. The browser caches this policy and refuses to make HTTP requests to the domain for the duration of max-age (31536000 seconds = 1 year). After the first HTTPS visit, the user is protected even on public Wi-Fi.

HSTS directives

  • max-age — Duration in seconds to enforce HTTPS. Minimum recommended: 31536000 (1 year).
  • includeSubDomains — Extends HSTS to all subdomains. Required for preloading.
  • preload — Requests inclusion in browsers' built-in HSTS preload list. After preloading, even the first connection is always HTTPS — no HTTP request is ever made.

Recommended HSTS configuration

Strict-Transport-Security:
  max-age=31536000;
  includeSubDomains;
  preload

Before adding preload, confirm that all subdomains serve valid HTTPS. Submit to hstspreload.org after your configuration is stable.

Clickjacking and X-Frame-Options

Clickjacking is an attack where a malicious website embeds your page in a transparent or hidden iframe and tricks users into clicking UI elements they cannot see. Classic examples include invisible "Confirm Transfer" buttons over attractive content, or invisible permission prompts positioned under a game button.

X-Frame-Options is the traditional header to prevent this:

  • X-Frame-Options: DENY — prevents all iframe embedding.
  • X-Frame-Options: SAMEORIGIN — allows embedding only on the same origin.

The modern replacement is the CSP frame-ancestors directive, which is more flexible and is supported by all current browsers. You can use both X-Frame-Options and frame-ancestors simultaneously for compatibility with older browsers:

X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'

What Referrer-Policy controls

When a user clicks a link on your site and navigates to another, the browser includes a Referer header with the URL of the page they came from. Without a Referrer-Policy, this can leak sensitive information: query strings containing search terms, session tokens, user IDs, or internal dashboard paths all end up visible to the destination site's server logs and analytics.

ValueSame-originCross-originRecommended?
no-referrerNothingNothingGood (very private)
strict-origin-when-cross-originFull URLOrigin onlyBest balance
strict-originOrigin onlyOrigin onlyGood
originOrigin onlyOrigin onlyAcceptable
no-referrer-when-downgradeFull URLFull URL (HTTPS→HTTPS only)Old default
unsafe-urlFull URLFull URL alwaysAvoid

The recommended value is strict-origin-when-cross-origin, which sends the full URL for same-origin navigation (useful for analytics) but only the origin for cross-origin requests (prevents leaking paths and query strings to third parties).

Permissions-Policy: controlling browser feature access

Permissions-Policy (previously named Feature-Policy) lets you declare which browser APIs and hardware features your page is allowed to use — and, crucially, which it should explicitly not use. If an XSS payload or malicious third-party script tries to access the camera or microphone, Permissions-Policy can prevent it outright.

Features you can control include: camera, microphone, geolocation, payment, accelerometer, gyroscope, magnetometer, fullscreen, autoplay, encrypted-media, picture-in-picture, and more.

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

The empty parentheses () mean "allowed for no origin" — completely disabled. If your site legitimately uses one of these features (e.g. geolocation for a store locator), use geolocation=(self) to restrict it to your own origin only.

How to add security headers to your server

Security headers are configured at the server or CDN level — not in HTML. The exact syntax depends on your stack.

Nginx

add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Apache

Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Cloudflare (Transform Rules)

Go to Rules → Transform Rules → Modify Response Header. Add headers as static values. Cloudflare applies them to all matching requests without changing your origin server.

Node.js / Express

// npm install helmet
const helmet = require('helmet');
app.use(helmet());

Helmet sets sensible defaults for all major security headers and is the recommended approach for Express applications.

Frequently asked questions

What is an HTTP security header?

An HTTP security header is a response header set by a web server that instructs the browser how to handle the page. Security headers defend against attacks like XSS, clickjacking, MIME-type confusion, and protocol downgrade — without any changes to your HTML or JavaScript. They are configured once in your server or CDN and protect every user of your site automatically.

What is Content Security Policy and why is it important?

Content Security Policy (CSP) tells the browser exactly which scripts, stylesheets, images, and other resources are allowed to load on your page. Without a CSP, any JavaScript injected via an XSS vulnerability runs with full access to cookies, localStorage, and sensitive user data. A strong CSP blocks injected scripts entirely. Use Content-Security-Policy: default-src 'self' as a starting point and add exceptions only where needed. Avoid 'unsafe-inline' and 'unsafe-eval' in your CSP.

What is HSTS and how do I enable it?

HSTS (HTTP Strict Transport Security) forces browsers to always use HTTPS with your site. Without it, an attacker on the same network can intercept the user's first HTTP request before they get redirected to HTTPS — an SSL stripping attack. Enable HSTS by adding: Strict-Transport-Security: max-age=31536000; includeSubDomains. In Nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; In Cloudflare: Security > Edge Certificates > HTTP Strict Transport Security.

What is clickjacking and how is it prevented?

Clickjacking embeds your page in a hidden iframe on an attacker's site, tricking users into clicking invisible buttons. To prevent it, add: X-Frame-Options: DENY — blocks all iframe embedding. Or use the more modern CSP directive: Content-Security-Policy: frame-ancestors 'none'. If you need your own site to embed the page: use SAMEORIGIN or frame-ancestors 'self'. Both methods work in all current browsers.

What does the Referrer-Policy header do?

Referrer-Policy controls what URL information is sent in the Referer header when a user follows a link from your site. Without this header, the browser may send the full URL — including paths and query strings that could contain session tokens, user IDs, or private information — to the destination site's logs. The recommended value is Referrer-Policy: strict-origin-when-cross-origin, which sends the full URL only for same-origin navigation and only the origin (e.g. https://example.com) for cross-origin requests.

What does Permissions-Policy do?

Permissions-Policy (formerly Feature-Policy) restricts which browser APIs your page and any embedded iframes can access. You can disable camera, microphone, geolocation, payment, and other sensitive APIs outright. This limits damage if an XSS vulnerability or malicious third-party script tries to access device hardware. Example: Permissions-Policy: camera=(), microphone=(), geolocation=(). Use (self) instead of () for features your own site legitimately needs.

How do I fix missing security headers?

Security headers are added in your web server, CDN, or application middleware — not in HTML. In Nginx: add_header Header-Name "value" always; In Apache: Header always set Header-Name "value" In Cloudflare: use Transform Rules > Modify Response Header. In Express.js: use the Helmet package (npm install helmet; app.use(helmet())). In Cloudflare Pages: add a _headers file to your build output with each header on its own line.

Are security headers required for compliance?

Yes — several standards require or strongly recommend security headers. PCI DSS v4.0 requires a Content-Security-Policy on all payment pages. OWASP ASVS mandates HSTS, CSP, X-Content-Type-Options, and X-Frame-Options. SOC 2 Type II auditors frequently check web application security headers as part of the CC6 (logical access) and CC7 (system operations) controls. HIPAA security rule risk analysis should include security headers for any web application handling PHI.