What the web module tests on your HTTPS setup, why each check matters and how it is scored – including the rating caps a single serious finding can trigger.
Check your domain →
Last updated: July 2026 · 23 checks documented
HTTPS reachable (port 443) #
Every web check starts with a TLS connection to port 443. If no connection can be established (no service listening, firewall, DNS pointing nowhere), none of the certificate, protocol or cipher checks can run – and visitors cannot reach the site securely either.
RatingOnly appears when the connection fails: fail, weight 3. The remaining web checks are then skipped.
How to fix itMake sure a web server listens on port 443 for this name, the firewall permits it, and the DNS records point to the right address. Then re-run the scan.
Target address blocked (scanner protection) #
The domain resolves to a private, loopback or otherwise internal IP range (e.g. RFC 1918). The scanner deliberately refuses to contact such addresses: following them would let arbitrary domains turn the scanner into a probe of its own internal network (server-side request forgery). This is a property of the scan target’s DNS setup, not of your server’s security.
RatingOnly appears when the scan is aborted for this reason: fail; the module is not meaningfully gradeable. Point the name at a public address and re-scan to get a real result.
How to fix itFor a public website, the domain must resolve to a publicly routable IP address. Split-horizon or internal-only names cannot be scanned from the outside.
Certificate chain valid & trusted #
Browsers only trust certificates whose chain leads to a publicly recognized certificate authority (CA). A self-signed certificate, or one issued by an unknown CA, triggers a security warning. The chain is validated against a combined, up-to-date root store (operating system + Node bundle + the CCADB/Mozilla TLS roots, distrusted roots excluded) – an outdated store would reject new legitimate roots or wrongly accept removed ones. If the served chain is merely incomplete, it is re-validated once using the publicly disclosed CCADB intermediates (refreshed weekly) as chain-building material – the same set Firefox preloads and Chrome/Safari fetch via AIA – to distinguish a repairable chain from a genuinely untrusted one.
Ratingfail → special grade T (Trust); this completely overrides the A+…F grade. Weight 3. Exception: an incomplete chain that validates with a publicly disclosed CCADB intermediate is warn instead (no T – the grade is capped at B via "Complete certificate chain"). The hostname is checked separately (see "matches the hostname").
How to fix itUse a certificate from a public CA (e.g. free via Let’s Encrypt) and serve the complete chain. ACME automates issuance and renewal.
Certificate matches the hostname #
The requested hostname must appear in the certificate’s Subject Alternative Names (SAN). Otherwise there is no proof that the certificate belongs to exactly this website.
Ratingfail → special grade M (Mismatch); overrides the letter grade. Weight 2.
How to fix itAdd the hostname (and www if applicable) to the SAN list, or have a matching certificate issued.
Certificate time remaining #
An expired certificate causes a hard error in every browser – the site is effectively unreachable.
Ratingpass > 15 days; warn ≤ 15 days; expired → fail + Cap F. Weight 1.
How to fix itAutomate renewal (ACME/Let’s Encrypt, certbot, Caddy). Set up monitoring of expiry dates.
Certificate signature algorithm #
SHA-1 and MD5 are collision-prone – certificates signed with them are considered forgeable and are rejected by browsers.
Ratingpass with SHA-256+; SHA-1/MD5 → fail + special grade T. Weight 1.
How to fix itHave the certificate reissued with SHA-256 (or stronger) – standard at modern CAs.
Key strength #
Keys that are too short can be broken. Recommended: RSA ≥ 2048 bits or ECDSA P-256 (≈ RSA 3072).
Ratingpass with RSA ≥ 2048 / EC ≥ 256 / Ed25519; RSA < 2048 → warn + Cap B; RSA < 1024 → fail + Cap F. Weight 1.
How to fix itGenerate a new key with RSA-2048+ or ECDSA P-256 and reissue the certificate.
Complete certificate chain #
If the intermediate certificates are not included, many clients cannot build the chain – even though the certificate is valid. Browsers usually recover (Firefox preloads all publicly disclosed intermediates, Chrome/Safari fetch the missing certificate via AIA), but strict clients such as curl/OpenSSL, most mail servers and older Java fail.
Ratingfail → Cap B if only the leaf certificate is served or the issuer cannot be resolved. Weight 1. The scanner reports whether the missing link is a publicly disclosed CA certificate (checked against the ~1,700 CCADB intermediates, refreshed weekly); if not, the chain counts as untrusted (special grade T via "valid & trusted").
How to fix itConfigure the complete chain (leaf + all intermediates). Tools like "what’s my chain cert" help with assembling it.
DANE / TLSA (HTTPS) #
DANE binds the website certificate to a DNSSEC-secured TLSA record under _443._tcp, hardening TLS against MITM/mis-issuance. Note: mainstream browsers do not enforce DANE for HTTPS, so it mainly protects DANE-aware clients and documents certificate intent. For auto-renewed certificates, usage 2 (DANE-TA, pinning the CA) survives key rotation, whereas usage 3 (DANE-EE, leaf SPKI) must be republished on every renewal unless the key is reused.
Ratingpass if a DNSSEC-secured TLSA matches the served chain; fail on mismatch or missing DNSSEC (Cap C). PKIX-TA (usage 0) exceptions: pinning a sent intermediate is a mild warn (no cap; DANE-TA is cleaner), and a usage-0 record that pins the not-sent root is info (no penalty; validated via the client trust store). A DANE-TA (usage 2) record whose only match is a sent root via a hash form (e.g. 2 1 1) still passes but carries a note recommending a 2 0 0 record (full root cert in DNS) – a sent cross-signed root leaves the chain once its cross-signature expires; a record that already pins the root via 2 0 0 is recognised as robust and passes cleanly. Absence is info only. Weight 2 when present, 0 when absent.
How to fix itOptional but recommended: enable DNSSEC and publish a TLSA record under _443._tcp (usage 2 / selector 1 / matching 1 pinning the CA is the most robust for ACME-renewed certificates). During a rollover, publish the old and new records in parallel. The TLSA generator can fetch the live HTTPS certificate (port 443) and build the record for usage 2 or 3.
Certificate total lifetime #
The CA/Browser Forum limits the maximum validity of leaf certificates, and ballot SC-081 shrinks the cap stepwise by issuance date: 398 days → 200 days (issued from 2026-03-15) → 100 days (2027) → 47 days (2029). Long lifetimes increase the risk in the event of key compromise; browsers may reject over-long certificates outright.
Ratingwarn when the lifetime exceeds the limit applicable at the issuance date. Weight 1.
How to fix itUse short-lived certificates with automatic renewal (ACME) – e.g. Let’s Encrypt (90 days).
Certificate Transparency (SCT) #
Certificate Transparency logs issued certificates publicly and makes mis-issuance detectable. Chrome requires valid SCTs for certificates issued since 2018. Embedded SCTs are universal at public CAs today, so this finding only appears when they are MISSING.
RatingOnly shown if no embedded SCTs are found: warn for certificates issued after 2018-04-30 (they can alternatively be delivered via OCSP/TLS), info otherwise. Informational (weight 0).
How to fix itObtain the certificate from a CA with CT logging – standard at public CAs today (SCTs embedded).
Revocation (CRL/OCSP) #
If a certificate is compromised and revoked, clients must be able to check the revocation status – via CRL or OCSP (the addresses are in the certificate: CRL distribution points / AIA). With OCSP stapling, the server additionally delivers the signed revocation status directly in the handshake – faster and more privacy-friendly than having every client query the CA. NOTE: the industry is retiring OCSP (CA/B Forum ballot SC-063 made it optional in 2023). This scanner maintains a list of CAs that have retired OCSP or announced it – currently Let's Encrypt (responders shut down August 2025), Google Trust Services (no OCSP URLs in new certificates since H2 2025), and HARICA (no OCSP URLs since March 2026, responders off by May 2027). For certificates from these CAs a missing staple is never reported as a server shortcoming.
Ratingpass if CRL and/or OCSP information is present (weight 1; with active OCSP stapling weight 2 – a small bonus); warn if the certificate contains neither. CRL-only is the modern norm (browsers use CRL-fed lists like CRLite/CRLSets). A stapling recommendation only appears while the issuing CA still operates OCSP; no LIVE OCSP query is performed.
How to fix itObtain the certificate from a CA that publishes CRL and/or OCSP information (every publicly trusted CA does). Only if the CA keeps operating OCSP: optionally enable stapling (Caddy: automatic; nginx: ssl_stapling on).
OCSP Must-Staple #
If the certificate carries the Must-Staple flag, servers MUST staple an OCSP response – otherwise browsers reject the connection. This protects against stapling failing unnoticed.
Ratingpass if Must-Staple is required AND stapling is active; warn if required but no stapling. Weight 1.
How to fix itEither enable stapling reliably or do not set the Must-Staple flag.
TLS protocol versions #
TLS 1.2 and 1.3 are the secure, current protocols – TLS 1.3 is additionally faster (1-RTT) and removes outdated cryptography. TLS 1.0/1.1 are formally deprecated (RFC 8996): they rely on outdated primitives (SHA-1, CBC without AEAD), are exposed to the BEAST attack, and have been rejected by all major browsers since 2020. The drill-down shows the full offered/disabled matrix per version.
Ratingpass if only TLS 1.2/1.3 are offered; warn + Cap A- if TLS 1.3 is missing; fail if neither 1.2 nor 1.3 is negotiated, or + Cap B if legacy TLS 1.0/1.1 is still active. Weight 3.
How to fix itEnable TLS 1.2 and 1.3 (TLS 1.3 requires a current OpenSSL/server version) and disable TLS 1.0/1.1 on the server side.
HTTP versions (1.1 / 2 / 3) #
One verdict over the application-protocol generations. HTTP/1.1 is the universal baseline every server speaks – it carries no signal and is only listed for completeness. HTTP/2 multiplexes many requests over one TLS connection (negotiated via ALPN h2 in the handshake – also a marker of a modern TLS stack). HTTP/3 runs over QUIC (UDP 443) and reduces latency further; servers advertise it via Alt-Svc: h3=…. Besides the advertisement, the QUIC endpoint itself is probed: a long-header packet with a deliberately unknown version forces a Version Negotiation answer (RFC 8999/9000 §6) that proves a live QUIC listener and reveals the supported versions (v1 = RFC 9000, v2 = RFC 9369) – without any TLS handshake. All of this is performance/quality, not a security control.
Ratingpass when the server negotiates h2 via ALPN (weight 1); HTTP/1.1 only → info only (weight 0, not penalized). The HTTP/3 state (advertised / QUIC endpoint answering / both) is reported in the value and detail without affecting the grade. A QUIC probe timeout is only interpreted as "endpoint silent" when reference probes (cached) confirm the scanner’s own outbound UDP/443 path works; otherwise it is reported as "not verifiable".
How to fix itEnable HTTP/2 in the web server (e.g. nginx http2 on;, Apache Protocols h2 http/1.1). For HTTP/3: nginx listen 443 quic plus an Alt-Svc: h3=":443"; ma=86400 response header, open UDP 443, and ideally an HTTPS DNS record with alpn=h3.
Perfect Forward Secrecy #
With PFS (ECDHE/DHE), a later-compromised server key does not retroactively expose recorded traffic. TLS 1.3 always provides PFS.
Ratingpass with ECDHE/DHE or TLS 1.3; otherwise warn + Cap B. Weight 1.
How to fix itPrefer cipher suites with ECDHE; disable static RSA key exchange.
Diffie-Hellman parameter strength #
Weak DH groups (< 2048 bits) enable Logjam downgrade attacks. ECDHE is preferable to DH parameters.
Ratingpass ≥ 2048 bits; warn 1024–2047 (Cap B); < 1024 → fail + Cap F. Weight 1.
How to fix itSet DH parameters to ≥ 2048 bits or use ECDHE exclusively.
Cipher suites & AEAD #
Weak cipher suites undermine encryption: RC4 and 3DES are broken/outdated, NULL means no encryption, and export/anonymous suites are trivially exploitable. AEAD availability is part of the same verdict: AEAD ciphers (AES-GCM, ChaCha20-Poly1305) encrypt and authenticate in one step and avoid the padding-oracle attacks of the older CBC suites. The drill-down lists the offered suites per TLS version: TLS ≤ 1.2 suites are enumerated iteratively, the TLS 1.3 suites (a fixed set of five per RFC 8446 Appendix B.4 – all AEAD with forward secrecy by design) are probed individually. Note on naming: OpenSSL uses its own short names for TLS ≤ 1.2 suites (e.g. ECDHE-RSA-AES128-GCM-SHA256), while the TLS standards (RFC 2246/4346/5246) and the IANA registry name the same suite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 – the drill-down therefore shows both, so results are directly comparable with SSL Labs, testssl.sh and vendor documentation. Only for TLS 1.3 did OpenSSL adopt the RFC 8446 names unchanged.
RatingNULL/export/anonymous → fail + Cap F; RC4 → Cap B (Cap C with TLS 1.1+); 3DES with TLS 1.1+ → Cap C; no AEAD suites at all → warn + Cap B. TLS-1.3-only servers pass with the offered 1.3 suites. Weight 3.
How to fix itAllow only modern AEAD suites (AES-GCM, ChaCha20-Poly1305); disable RC4/3DES/CBC-only/export/NULL.
Web server backends (per IP) #
A domain behind round-robin DNS or a CDN resolves to several A/AAAA addresses. The detailed TLS checks above connect by hostname and therefore reflect just one backend (whichever IP the resolver returned). To catch a server that is misconfigured on only some of its addresses without re-running the heavy cipher enumeration against every IP, this check fully profiles one representative per family (one IPv4 and one IPv6 – certificate, TLS versions, full cipher enumeration) and confirms the remaining IPs with a single handshake (certificate fingerprint + negotiated suite). Identical fingerprints across all of them mean the backends are interchangeable (the CDN/anycast case); a divergence is flagged. The connection targets the IP directly while still sending the hostname as SNI. A CDN provider is named when the IPs’ reverse DNS or the host’s CNAME reveals one (e.g. CloudFront, Akamai, Fastly, Cloudflare).
Ratingpass when all reachable backends share one certificate + negotiated suite; warn (weight 1) when they diverge. Addresses the scanner cannot route to (e.g. IPv6 without an IPv6 egress) are marked “not testable”, not counted against the server.
How to fix itServe an identical TLS configuration and certificate from every backend so the security a client gets does not depend on which IP it happens to reach.
Server cipher preference (TLS ≤ 1.2) #
If the server determines the cipher order, it can always enforce the strongest common suite. If it follows the client, a weak client can force a weaker suite – but only if weaker suites are offered at all. Modern stacks (Go/Caddy, BoringSSL) deliberately follow the client so devices without AES hardware can pick ChaCha20; Go removed the server-preference option entirely. Scope: the toggle (nginx ssl_prefer_server_ciphers, OpenSSL SSL_OP_CIPHER_SERVER_PREFERENCE) only governs TLS ≤ 1.2. It does NOT apply to TLS 1.3, where the server always selects the suite from its own order – which is why this check is labelled "TLS ≤ 1.2". The probe is run at TLS 1.2 (representative, since it is a single server-wide setting covering 1.0/1.1/1.2).
Ratingpass if the server enforces its own order; client-decided order with an all-strong suite set (AEAD + forward secrecy, nothing weak) is harmless (light-green check, not graded); warn only when client-decided AND weaker suites are offered. Not applicable to TLS 1.3 (server always decides there).
How to fix itOnly needed when weaker suites are offered: enable "honor server cipher order" (nginx: ssl_prefer_server_ciphers on) – or better, remove the weak suites.
Hash function for key exchange #
The server signs the ephemeral key exchange (ServerKeyExchange) of every forward-secret (ECDHE/DHE) suite. The hash used depends on the TLS version. TLS 1.0/1.1 have no signature_algorithms negotiation, so the hash is fixed by the protocol – RSA suites use MD5+SHA-1, ECDSA uses SHA-1 – meaning every forward-secret suite on these versions relies on broken SHA-1, which cannot be configured away. TLS 1.2 negotiates the hash. What matters is the hash a real client actually gets: browsers offer SHA-256 and stronger and never SHA-1/SHA-224, so a server that supports any modern hash signs strong for them. We therefore check whether the server can sign with SHA-256+ at all; only if it cannot (it tops out at SHA-224 or SHA-1) is a normal client downgraded. A server that merely tolerates SHA-224 when a client offers nothing else (almost all do, e.g. CloudFront/Amazon) is not flagged – that would be a false positive. TLS 1.3 enforces SHA-256+ by design. The drill-down lists, per TLS version, the exact cipher suites whose key exchange is signed with a weak hash. Static-RSA suites (TLS_RSA_*) send no ServerKeyExchange and are unaffected.
RatingChecked per offered TLS version. pass if normal clients get SHA-256+; warn (weight 1) if TLS 1.2 cannot sign with SHA-256+ and tops out at SHA-224; fail (weight 2) if SHA-1 is used – automatically on every forward-secret suite over TLS 1.0/1.1, or on TLS 1.2 if the server offers no hash stronger than SHA-1.
How to fix itDisable TLS 1.0 and TLS 1.1 (their SHA-1 key-exchange signatures are not configurable). On TLS 1.2 restrict the server signature algorithms to SHA-256+, e.g. nginx/OpenSSL: ssl_conf_command SignatureAlgorithms ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512 (RSA certs: add RSA-PSS+SHA256/384/512).
Client compatibility (simulation) #
A simplified handshake simulation shows which reference clients (browsers, Android, Java, OpenSSL) can connect. Only clients whose OS/runtime still receives security updates are simulated – end-of-life clients (Android ≤7, IE 11, Java 8, OpenSSL 1.0.x) are deliberately excluded, because their compatibility carries no signal for a current TLS configuration.
Ratingwarn if ANY simulated reference client (Chrome/Firefox/Safari current, Android 14, Java 17, OpenSSL 3.x) cannot connect; otherwise pass. Weight 1.
How to fix itIf a supported client fails, the TLS configuration is too restrictive or faulty – check protocols/ciphers.
HTTP-to-HTTPS redirect #
If someone visits the site over http://, it should immediately redirect to https:// – otherwise the session starts unencrypted and can be tampered with.
Ratingpass with a 301/302 to an https URL; fail if HTTP is served without a redirect; skip if port 80 is closed. Weight 2.
How to fix itPermanently redirect all HTTP requests to HTTPS via 301 (also set HSTS).