What we check, and what we don't
Updated 29 October 2026 · Prime Dev Force · scoring model pdf-health-v3
Each scan sends ordinary GET requests to https://<domain>/ and http://<domain>/ (following at most 5 redirects), opens up to two short TLS connections to port 443 to read the certificate, and reads public DNS records through Cloudflare's DNS-over-HTTPS resolver. If MTA-STS is announced, we also fetch the published policy file. It also looks the domain up in public Certificate Transparency logs (crt.sh) and blocklists (Google Web Risk, abuse.ch URLhaus). Every check reports exactly one of: Passed, Issue found, Could not complete, Not tested or Not observable.
HTTPS, certificates and redirects
- HTTPS availability
web.https - Requests the homepage over HTTPS. Establishes whether the site answers over HTTPS from Cloudflare's network. A timeout is reported as "could not complete", never as "HTTPS missing". The certificate itself is checked by the three checks below.
- Certificate expiry
tls.cert_expiry - Reads the certificate your server sends during a TLS 1.2 connection to your first public address on port 443, and checks its dates: expired or not yet valid (high), expiring within 14 days (medium) or 30 days (low). The connection is closed before the handshake completes.
- Certificate name and chain
tls.cert_chain - Checks that the certificate's Subject Alternative Names cover the hostname (wildcards cover exactly one label), that it isn't self-signed, that the server sends the intermediate certificate that issued it, and that no certificate it sends has expired. This is a completeness check: signatures are not validated against a trusted root store, so we never say a certificate is "trusted".
- Legacy TLS versions
tls.protocols - Offers a connection limited to TLS 1.1 or older. If the server accepts, it still allows deprecated protocols (medium). A refusal passes. No answer is "could not complete". SSL 3.0 and cipher strength aren't tested separately.
- HTTP to HTTPS redirect
web.http_redirect - Requests the homepage over plain HTTP and checks that the final URL is HTTPS.
- Redirect chain safety
web.redirect_chain - Flags HTTPS→HTTP downgrades, loops and chains longer than 5 hops.
- HSTS
web.hsts - Reads Strict-Transport-Security on the final HTTPS response and checks
max-age(at least 180 days recommended).
When we can't read the served certificate. Cloudflare doesn't allow our scanner (which runs on Cloudflare Workers) to connect directly to addresses on Cloudflare's own network, so sites served through Cloudflare can't be probed. Servers that only accept TLS 1.3 encrypt their certificate. In both cases the three checks report "could not complete", and the expiry check shows the most recently logged certificate for the hostname from Certificate Transparency logs instead, clearly labelled, because it may not be the one the server sends. That fallback can raise an expiry warning, but it never counts as a pass.
Security headers
- Content Security Policy
headers.csp - Missing, report-only, or allowing
'unsafe-inline'(without nonces or hashes) or'unsafe-eval'for scripts. Policies set in<meta>tags are not evaluated. - Clickjacking protection
headers.framing - X-Frame-Options DENY/SAMEORIGIN or CSP
frame-ancestors. - MIME sniffing protection
headers.xcto X-Content-Type-Options: nosniff.- Referrer-Policy
headers.referrer - Header or
<meta name="referrer">.unsafe-urlis flagged. - Permissions-Policy
headers.permissions - Presence only (informational).
- Software version disclosure
headers.disclosure - Version numbers in Server, X-Powered-By and similar headers. These strings can be altered, so this is an indicator only.
- Cookie security flags
headers.cookies - Secure, HttpOnly and SameSite on cookies set by the homepage response. Cookie values are never recorded. Cookies set elsewhere or by JavaScript aren't seen.
DNS
- Address records
dns.resolution - A and AAAA records. A domain resolving to a private or reserved address is refused and not scanned.
- DNSSEC validation
dns.dnssec - The AD flag from Cloudflare's validating resolver. A SERVFAIL is reported as "could not complete" because it can indicate a broken DNSSEC chain.
- CAA
dns.caa - CAA records at the hostname and up to two parent domains.
Email authentication
- MX
email.mx - Mail servers, including null MX (a deliberate "no email" signal).
- SPF
email.spf - One record only, valid terms, the final
allqualifier, and the 10-DNS-lookup limit counted through include and redirect (bounded to 10 lookups and 4 levels). Macros are not expanded. - DMARC
email.dmarc - One record, valid
p=policy,pctandrua. For subdomains, the parent's record is used if the subdomain has none. This approximation does not use the Public Suffix List. - DKIM
email.dkim - Only for a selector you supply. Selectors can't be listed through DNS, so without one the check is "not tested" and says nothing about whether DKIM exists.
- MTA-STS
email.mta_sts - The
_mta-stsTXT record and the policy file (fetched without following redirects, as RFC 8461 requires): version, mode, max_age, and whether every MX host is covered. - SMTP TLS reporting
email.tls_rpt - The
_smtp._tlsTXT record with a reporting address.
Email checks run against the domain you entered, with a leading www. removed.
Homepage indicators
- Mixed content
content.mixed - Scripts, stylesheets, frames and media referenced over http:// in the first 512 KiB of the HTTPS homepage HTML.
- Public CMS indicator
content.generator - A
<meta name="generator">tag that announces a version. We never claim a site is vulnerable from this alone. - Third-party scripts
content.third_party_scripts - Lists the
<script src>tags in the homepage HTML that load code from other sites, as any visitor's browser would. Flags a host on our sourced list of known-compromised script hosts (high; the list starts with polyfill.io and related domains from Sansec's June 2024 advisory), a script host that returns NXDOMAIN (medium; high and "likely" when its whole domain doesn't exist, because anyone could register it), and fixed third-party files without an integrity (SRI) hash (low). Tag managers, analytics and payment widgets change by design and aren't flagged for SRI. Up to 4 hosts are looked up in DNS. Scripts added later by JavaScript aren't seen, so the list is a lower bound.
Security contact
- security.txt
disclosure.security_txt - Requests
/.well-known/security.txt(and the legacy/security.txtif needed) and checks what RFC 9116 requires: at least one Contact, exactly one Expires date in the future, plain text over HTTPS. No file is informational (no deduction); a broken or expired file is low. We don't check that the contact works or that a signature is valid.
Exposed files (verified owners only)
- Exposed deployment files
exposure.files - Requests
/.git/HEADand/.envwithout following redirects, plus one random path as a baseline. A file is reported only when its content matches what that file really contains and differs from the baseline, so sites that answer every path with the same page don't produce false alarms. A readable.gitis high; a readable.envis critical. Secret values are never stored or shown: we keep only the variable names. This runs only for owners who verified their domain, because on someone else's site it would be reconnaissance. Other paths (backups, other config files, directory listings) aren't checked, and a 403 answer is treated as neither safe nor exposed.
CDN and firewall
- CDN / web application firewall
protection.edge - Looks for response headers that identify a CDN or WAF provider (Cloudflare, Sucuri, Akamai and others). A detected provider proves traffic passes through it, not which protections are switched on. Some firewalls leave no trace in headers.
Blocklist reputation
- Blocklist reputation
reputation.blocklist - Looks up
https://<domain>/in Google Web Risk (which checks Google's Safe Browsing lists) and the hostname in abuse.ch URLhaus. A listing there (high) means browsers that use Safe Browsing may warn visitors; it's reported as "suspected". URLhaus URLs that were recently online are high; past reports only are low. If neither lists the site, the result is "Not listed in the sources checked", with the time of the check. That doesn't mean the site is free of malware or phishing. If a source can't be reached, the check is "could not complete".
Malware indicators (verified owners only)
These run only in monitoring scans for domains whose owner has verified ownership, because they make crawler-like requests and their results would be inappropriate to publish about someone else's site.
- Malware indicators in homepage HTML
malware.content - Browser cryptominers, obfuscated script execution, card-skimmer patterns, redirects for search-engine visitors, scripts from raw IP addresses, hidden iframes to other sites, and hidden spam links in the first 512 KiB of the homepage.
- Cloaking and conditional redirects
malware.cloaking - Compares the homepage as seen by a normal visitor, a search-engine crawler, and a visitor arriving from a search result. Flags off-site redirects or spam shown only to some of them.
These are indicators to confirm, not proof. For file-level checks, install the server agent.
Subdomains and pages (verified owners, weekly)
For a domain whose owner has proved ownership, we also run a weekly check of:
- Up to 10 subdomains, found in Certificate Transparency logs and DNS (
www,mail, and mail and name servers inside the domain). A name is checked only if it resolves to public addresses. Each gets the HTTPS, redirect, header, content, CDN and certificate checks above. - Up to 5 pages where problems matter most: sign-in, checkout, cart and contact pages linked from the homepage, then
/login,/wp-login.php,/checkout,/cartand/contact. Each gets the header, cookie, mixed-content and malware-indicator checks.robots.txtis followed, and pages that redirect to another site aren't followed there.
The dashboard shows exactly what was covered, for example: "Scanned: homepage, 3 of 6 pages (1 disallowed by robots.txt; 2 not found), 4 of 7 subdomains found (cap 10; 3 didn't resolve)". Results are listed per host. They never change the headline Site Health score, which stays the homepage score. This isn't done for unverified domains: on someone else's domain it would be reconnaissance.
Not checked by this scanner
- Malware in files or the database, for the public scan. Verified owners get homepage malware indicators, and the server agent checks files and, on WordPress, the database (read-only).
- Known vulnerabilities in your CMS, plugins or server software, unless the server agent reports installed versions.
- Whether a certificate chains to a trusted root (signatures aren't validated), and the certificate of sites served through Cloudflare or that accept only TLS 1.3 (we show the most recently logged certificate instead).
- For the public scan: pages other than the homepage and subdomains. For everyone: content loaded by JavaScript.
- Blocklists other than Google Web Risk and URLhaus.
- Anything requiring login, and any form of attack or penetration testing.
- PCI DSS compliance. This is not a PCI scan or assessment.
See plans for what's available today and what's planned.