← All Tools

HTTP Security Headers Grader

Analyze HTTP security headers and get an A+ to F grade with fix recommendations.

The URL is fetched server-side to retrieve headers. No data is stored or logged.

How to check your security headers

  1. To test a live site, open Scan URL and enter an address such as https://example.com (the scheme is added if you leave it out). The page is fetched from this server, following up to 3 redirects, and the final response headers are graded.
  2. To test headers you already have (a staging server, an internal app, a curl -sI output), open Paste Headers, paste the raw response headers, one per line, and press Analyze Headers. Pasted headers are graded in your browser and are not sent anywhere.
  3. Read the grade, then work through each header card from FAIL to WARN.
  4. Use Export JSON or Export Markdown to keep the report or paste it into a ticket.

How the grade is computed

The score starts at 100. Each scored header applies a signed point change; the total is clamped to the range 0–120 and mapped to a letter. The formula is fixed and documented here so the same headers always produce the same grade (ruleset shown on every result).

ScoreGradeScoreGrade
110 and aboveA+70–79C
90–109A60–69D
80–89Bbelow 60F

Per-header point impacts:

HeaderBestPartialMissing / bad
Content-Security-Policy+25+5 (warnings)−25
Strict-Transport-Security+20+15 / +10 / +5−20
X-Frame-Options / frame-ancestors+100 (bad value)−15
Referrer-Policy+10+5 / 0−10
X-Content-Type-Options+50 (bad value)−5
Permissions-Policy+5—−5
Set-Cookie flags+15 (or +5 none)—−5 (issues)
X-XSS-Protection, COOP, COEP, CORP0 — informational only, never changes the grade
  • Content-Security-Policy (largest weight): missing is a fail. 'unsafe-inline' without a nonce or hash, 'unsafe-eval' or a wildcard script source downgrade it to a warning.
  • Strict-Transport-Security: needs a max-age of at least 6 months. Full points for max-age=31536000; includeSubDomains; preload. A value of max-age=0 turns HSTS off.
  • X-Frame-Options or CSP frame-ancestors: protects against clickjacking. Use DENY or SAMEORIGIN.
  • Referrer-Policy: strict-origin-when-cross-origin or stricter passes. unsafe-url leaks full URLs.
  • X-Content-Type-Options must be nosniff, and Permissions-Policy should switch off features you do not use.
  • Set-Cookie: every cookie should carry Secure, HttpOnly and SameSite. For a deeper look at each cookie, use the Cookie Analyzer.
  • X-XSS-Protection is deprecated: not setting it is correct; sending 1; mode=block is discouraged. It is reported for information but never changes the grade.
  • COOP / COEP / CORP (cross-origin isolation) are reported for information only. Like Mozilla Observatory and securityheaders.com, their absence does not lower the grade.

The grade covers response headers only. It does not test TLS, DNS or page content. Check the certificate with the SSL Certificate Checker.

Frequently asked questions

How do I check the security headers of a website?

Open the Scan URL tab, enter the address and press Scan. From a terminal, curl -sI https://example.com prints the same response headers, which you can paste into the Paste Headers tab.

What is a good Content-Security-Policy header?

A strict policy loads scripts only from your own origin or with per-request nonces, for example default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'. Avoid 'unsafe-inline' and 'unsafe-eval' in script-src. The CSP Builder helps you assemble one.

Do I still need X-Frame-Options if I have a CSP?

CSP frame-ancestors supersedes it in modern browsers, and this grader accepts either. Keeping X-Frame-Options: DENY as well costs nothing and covers older clients.

Should I set X-XSS-Protection?

No longer needed. Modern browsers removed the XSS auditor, and the old filter could itself be abused. If you send it at all, use X-XSS-Protection: 0 and rely on a strong CSP. It does not affect the score here.

Where do I add these headers?

In the web server or application that sends the response: add_header in nginx, Header always set in Apache (see the .htaccess generator), or middleware in your framework. A CDN can also add them. Re-scan afterwards to confirm the live response carries them.