Step 1: read what the host already says about itself
Every scan starts by recording what each host under your verified domains tells any visitor: the
Server and X-Powered-By headers, the page's generator tag and versioned
script URLs, and the greeting that SSH, FTP, mail and database services send on connect. That evidence
is normalized to products in a curated catalog (web servers, PHP, mail and FTP servers, content
management systems, DevOps tools such as GitLab and Jira, and VPN and edge appliances such as
NetScaler, FortiGate and Ivanti). Hosts come from the domains you verify and from certificate
transparency logs, so the forgotten staging server is included.
Take PHP2Shell, the two critical PHP flaws disclosed on October 21, 2026. A host that sends
X-Powered-By: PHP/8.2.20 has told the world exactly which PHP it runs. A host with
expose_php turned off has not.
Step 2: match the version against published ranges
Versions are matched against the affected-version ranges NVD publishes for each CVE, which we download nightly into our own store. For PHP2Shell, NVD lists PHP before 8.2.35, 8.3.36, 8.4.27 and 8.5.12 as affected, so the PHP/8.2.20 host above gets a critical finding for CVE-2026-109618 and one for CVE-2026-109619 on its next scan, while a host on 8.3.36 gets nothing.
Two details keep this accurate. First, new CVEs often arrive before NVD has mapped them to
versions: GitLab's CVE-2026-110264 sat in "Undergoing Analysis" for days. Matching starts on its own
the night NVD adds the ranges, with no rescan setup needed. Second, Linux distributions backport fixes
without changing the version number. When the header names a Debian or Ubuntu package build (such as
PHP/8.1.2-1ubuntu2.14), we check the distribution's own security tracker instead of the
upstream range, so a patched package is not reported as vulnerable.
Step 3: rank by what attackers are actually doing
Severity starts from the CVSS score and goes up a step when the CVE is on CISA's KEV catalog (exploitation observed) or its EPSS score says exploitation in the next 30 days is more likely than not. KEV and EPSS are refreshed nightly too, so when CISA lists a CVE, every host already running the affected version picks up the change on its next scan, and a newly exploited CVE is sent to your alert channels straight away. That is how listings like the FortiOS flaw behind PEERSTITCH reach the hosts that matter. We explain the reasoning in prioritizing vulnerabilities by exploitation.
When the version is hidden
Many products never show their version to an anonymous visitor: NetScaler, Ivanti Connect Secure,
FortiGate, GlobalProtect, GitLab, Confluence and Exchange among them. For those internet-edge products,
where exposure itself is the risk, we raise potential findings: only for CVEs on the
KEV catalog, capped at medium severity, tagged potential, and with instructions for
checking the real version. That is why a NetScaler sign-in page under your domain lights up the day
CISA lists a new NetScaler flaw.
We deliberately do not do this for everything. A web server or PHP install that hides its version could be any release from the last ten years, and a list of maybe-CVEs for it would be noise nobody reads. So a hidden PHP version produces no PHP2Shell finding, and the GitLab regex bugs (not on KEV) do not raise potential findings on GitLab hosts. For those, the inventory itself is the finding: you learn where the product is exposed and can check the version from the inside.
Certificates: checking the chain, not just the expiry date
For every TLS port we read the full certificate chain the host serves. Expiry, hostname coverage, weak keys, SHA-1 signatures and stalled renewals are the familiar checks, and new certificates issued for your domains show up from certificate transparency logs within minutes.
CA incidents need one more step. Our validation, like most software, uses a bundled copy of the
browsers' root store, but browsers block a compromised CA within hours through Chrome's CRLSets and
Mozilla's OneCRL, long before bundled copies catch up. When eMudhra's intermediate keys turned out to
be single bytes in October 2026, those chains still validated in a bundled store. So we keep a list of
CAs the browser root programs have blocked or removed and check every certificate in the served chain
against it, the way Chrome and Go do: by public key hash for compromised keys, and by issuer and
signature for removed roots. A chain through a compromised intermediate is tls.compromised-ca
(critical); a chain to a removed root such as emSign ECC Root CA - G3 is tls.distrusted-ca
(high). See the eMudhra post for
that incident.
What we do not do
- No exploit traffic. We never send payloads, try a bypass or crash a service to confirm a flaw. Everything above comes from ordinary requests any browser or mail server makes.
- No guessing. A hidden version, an unanalyzed CVE or a product outside the catalog means no CVE finding. The product still appears in your inventory, so you know where to check, and if the vulnerability data itself is unavailable the scan reports that matching was skipped rather than calling the host clean.
- No view inside. We cannot tell whether a host was already compromised, or see software that is not exposed. External scanning complements authenticated scanning and patch management; it does not replace them.
Frequently asked questions
How quickly does a new CVE show up in my results?
The vulnerability data refreshes nightly before the scheduled scans run. A CVE NVD has published with version ranges is matched on the next scan of any host announcing an affected version, and a CVE CISA adds to KEV raises its severity, and alerts, the same way.
Should I hide my software versions?
Hiding versions (expose_php off, server tokens off) is reasonable hygiene, but it is not a fix: attackers try exploits regardless. If you hide them, keep your own inventory of what runs where, because neither we nor anyone else outside can match CVEs to a version we cannot see.
Why did my certificate pass every other check but fail tls.distrusted-ca?
Because the browsers and your scan's bundled root store disagree. Browser root programs remove a CA faster than bundled stores are updated, so a chain can validate in older software while Chrome or Firefox rejects it. The finding names the CA and the date the browsers act; replace the certificate with one from a different hierarchy before then.