Methodology · Open formula
Health Score methodology v2.3
Open 0–100 formula: six categories, 120 raw points, normalised.
1. Security headers — 30 pts
| Header | Weight |
|---|---|
| Strict-Transport-Security (HSTS) | 6 |
| Content-Security-Policy (enforced) | 6 |
| X-Content-Type-Options | 4 |
| X-Frame-Options or CSP frame-ancestors | 4 |
| Referrer-Policy | 3 |
| Permissions-Policy | 3 |
| X-XSS-Protection | 2 |
| Cross-Origin-Opener-Policy | 2 |
A header present in the last response after all redirects earns its full weight; its value is not graded here (the value of the policy is graded in category 6). A Content-Security-Policy-Report-Only header does not count in this row. The X-Frame-Options row is also earned by a restrictive CSP frame-ancestors (v2.1).
2. SSL/TLS — 25 pts
- 10 — the certificate is in force: its period has started and not ended, the hostname is in the SAN (as browsers check it — SSL/TLS methodology v1.2), and more than 30 days remain; 6 if 30 days or fewer remain; 0 if it has expired, has not started or names another host
- 5 — the hostname is in the SAN; the CN is not used
- 5 — more than 30 days to expiry; 3 for 8–30 days; 0 for 7 or fewer
- 5 — the connection was negotiated over TLS 1.2 or TLS 1.3
The category is scored only when the final URL is HTTPS and the TLS probe answered; otherwise all 25 points are lost. The probe connects without verifying the chain, so neither the trust chain nor revocation (OCSP/CRL) affects these points — the /ssl tool shows both separately. Reference: Mozilla Server-Side TLS Guidelines.
3. Performance — 25 pts
- 10 — response time under 500 ms; 7 under 1000 ms; 4 under 2000 ms; 0 from 2000 ms
- 5 — the response is compressed (a Content-Encoding header)
- 5 — a caching header: Cache-Control, ETag or Expires
- 5 — a separate request to the URL negotiates HTTP/2 or HTTP/3
Response time is the full time of the request — every redirect plus the body (up to 2 MB) — measured from our server, not TTFB. Page size and the number of redirects are not scored on their own.
4. Best practices — 20 pts
- 5 — the final URL is HTTPS
- 4 — neither Server nor X-Powered-By is sent; 2 if only Server is; 0 if X-Powered-By is
- 4 — the final response is 2xx
- 3 — a Content-Type header is set
- 4 — no mixed content: no src, href or action pointing to http:// in the first 200 KB of an HTTPS page (a page served over HTTP is not checked and keeps these points)
5. Cookies — 10 pts
- 4 — HttpOnly
- 4 — Secure
- 2 — SameSite with a value: Strict, Lax or None
Each flag earns its weight times the share of first-response cookies carrying it, rounded: two of three cookies with HttpOnly earn round(2/3 × 4) = 3. A site that sets no cookies on the first response earns all 10.
6. CSP — 10 pts
- 10 / 8 / 6 / 4 / 2 — CSP policy graded A / B / C / D / F
- 0 — no Content-Security-Policy at all
The letter comes from the same grader as the standalone CSP Analyzer (src/csp-analyze.php). Without an enforced policy a Report-Only policy is graded, with the report-only finding.
Normalisation
The six categories sum to 120 raw points. The published 0–100 score is round(raw / 120 × 100), clamped to 0–100.
Grade letter mapping
round(raw / 120 × 100)
| Score | Grade |
|---|---|
| 95–100 | A+ |
| 85–94 | A |
| 70–84 | B |
| 50–69 | C |
| 30–49 | D |
| 0–29 | F |
Where else a «health» number appears
The Health badge (/badges), the public report /report/{domain}/health and the «Verified by Enterno» catalog do not show this score. They use a light formula from a HEAD request and a TLS handshake: HTTPS answering 2xx/3xx — 40; each of six headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) — 5; a TLS handshake — 30; capped at 100. Badge letters: A from 90, B from 80, C from 70, D from 60, E from 50, F below.
The API /api/v3/health and /api/v4/health compute the same formula as /health: the same engine (src/health-score.php), the same number and letter for the same response, and methodology_version with every score.
References
Versioning
Current version — v2.3, updated . The engine (src/health-score.php) returns the same version with every score, in methodology_version. Every change to the published formula — the weights or their description — is a new version with a line in the changelog above.
Calculator
Set what your site serves — the score follows the same rules as the /health check. The calculator makes no requests: you set the states yourself.