Skip to content
devtls

Web TLS grading

This page covers web TLS grading (src/grade.ts). Mail endpoints and mail DNS are graded separately by src/grade-mail.ts and src/grade-mail-dns.ts, and pasted configuration by src/config/analyze.ts — see mail-and-config.md for those rules and why they deliberately differ (no HSTS on port 993; a hostname mismatch warns rather than caps).

Each scan produces a numeric score (0–100) and a letter grade (A+→F), plus a list of concrete fixes. The logic lives in src/grade.ts and is fully unit-tested — this page documents it.

The native provider probes the endpoint directly (Node tls/https) for:

  • Protocol support — TLS 1.0, 1.1, 1.2, 1.3 (each tested individually).
  • Negotiated ciphers — classified weak / ok / strong. With opt-in cipher enumeration (--ciphers), every accepted TLS ≤1.2 suite is walked, so a weak suite the server accepts as a fallback (not just its preferred one) also trips the weak-cipher penalty.
  • Certificate — validity dates, days-until-expiry, chain trust, self-signed.
  • HSTS — presence, max-age, includeSubDomains, preload.

The host is resolved to all its A/AAAA addresses and each IP is probed independently. The inputs above are aggregated to the worst case across reachable addresses (a protocol counts as enabled if any address offers it; a weak cipher on any address counts), so a single grade reflects the weakest reachable IP. The certificate and HSTS are read from the primary (first reachable) address. Per-address detail is returned under addresses in the JSON output.

SSL Labs can optionally enrich the result with its own grade (stored under externalGrades); it does not change the computed score. SSLv2/SSLv3 cannot be probed from modern OpenSSL, so they are reported as not-detected (SSL Labs will flag them if present).

Start at 100, subtract penalties, then apply hard caps:

Finding Effect
SSLv2 or SSLv3 enabled grade F (score ≤ 20)
Certificate expired grade F (score ≤ 20)
Self-signed certificate score capped at 40
Untrusted chain score capped at 50
Certificate hostname mismatch score capped at 50
RSA key < 2048 bits −20 (< 1024 bits also caps at 40)
No forward secrecy −10
TLS 1.0 enabled −25
TLS 1.1 enabled −15
TLS 1.2 not available −20
TLS 1.3 not available −5
Weak cipher offered −20
HSTS missing −10
HSTS max-age < 6 months −3
Cert expires < 14 days −15
Cert expires < 30 days −5
Score Grade
95–100 A+
80–94 A
65–79 B
50–64 C
35–49 D
0–34 F

Every penalty also attaches a fix (id, severity, title, detail) shown on the domain detail page.