How VulnControl actually works
Written for whoever will be asked whether this tool is any good — a developer, a sysadmin, an agency lead, or the technically-minded owner doing the evaluation. It covers how software is identified, where the vulnerability data comes from, how findings are attributed, what the external attack-surface scan will and won't do, and where the boundaries are. The limitations section is not padding; it's the part worth reading first.
Looking for the plain-language version? VulnControl in business terms
What a scan does, in order
One job per website asset, on the platform's slow lane. Two gates run before anything touches the network, and the whole run lands as a single roll-up observation that becomes findings.
Server and X-Powered-By headers across 14 products, the <meta generator> tag for 7 CMSs, and WordPress plugin and theme assets carrying a ?ver= query — capped, so a large site doesn't turn into an unbounded enumeration. Each detection carries a confidence score set by the quality of the evidence behind it, not by how much we'd like it to be true.Why we keep our own copy, and how it's matched
The mirror is built from the NVD REST API and CISA's Known Exploited Vulnerabilities catalogue, refreshed nightly on a dedicated thread so a run lasting hours cannot delay anything else on the platform. Matching against it is the most important design area in the product, and the one where cheap scanners fail.
Matched on formal identifiers, not words
Version ranges are harvested only from CPE entries whose vendor:product pair is in the declared set for that product, and only for application-type CPEs. The vendor half is load-bearing: http_server belongs to Apache, Oracle and IBM, so matching on the product alone would file Oracle's version ranges under Apache's httpd.
Incident one: 110 false criticals
An early version ingested via keyword search — a full-text search over CVE descriptions — so every version range in any CVE that merely mentioned nginx was stored as nginx's. Once the download was fixed, nginx 1.24.0 matched 110 CVEs it does not have, most rated critical. Fixed by CPE filtering, plus skipping bounds-less wildcards rather than treating "affects everything" as a claim. Verified afterwards: nginx 1.24.0, zero matches.
Incident two: a false clean, which is worse
Later, one site showed nginx clean while another — same server, same version — flagged real flaws. Three compounding causes, none of them the CPE filter: keyword search had also missed CVEs whose write-ups never use the product name, including HTTP/2 Rapid Reset; one vendor CPE variant was absent; and the server hid its version, producing a silent green. All three fixed, and there's a regression test named after the gap that made a real nginx look clean.
Version resolution for hosts that hide it
Turning off version disclosure is common and sensible, but it means a component matches zero CVEs and reads as safe. Every genuine detection is remembered per host address and product, so a version-less component can inherit the last version actually seen on the same public address — one host is one binary. Only real detections are stored, so inheritance can never feed itself, and the provenance reaches the interface: you can see whether a version was observed or inherited.
Low severities are never ingested
Deliberate. The mirror cannot report them at all, because a report padded with trivia is a report nobody finishes. This is a choice, and it's a limitation — stated here rather than hidden.
Pruning that cannot delete what it just wrote
Stale entries are removed only when a fetch actually completed, and the cutoff timestamp comes from the database clock rather than the application's — a clock a few seconds ahead would otherwise delete the rows the sync had just written. The curated seed set is re-applied after every sync, because filtered ingestion legitimately doesn't reproduce all of it.
It makes ordinary connections and reads what is volunteered
The distinction between reconnaissance and attack is the whole basis on which this can run automatically against a customer's production site. It's enforced in code, not in policy.
What gets raised, and how hard
| Finding | What triggers it | Severity |
|---|---|---|
| Vulnerable component | A detected product and version matching one or more CVEs | The worst matched CVE — escalated to at least high when on the actively-exploited catalogue |
| Exposed database port | A database service answering from the public internet | Critical, fixed |
| Exposed admin port | Remote access or an administrative panel reachable publicly | High, fixed |
| Exposed sensitive file | A configuration file, backup, environment file or similar, publicly downloadable | The worst of the matched files' own severities |
| Server disclosure | A product identified but its version not established | Informational — an unknown version is not an all-clear, and not a vulnerability either |
Descriptions carry their own caveats: an actively-exploited match says so, and a match made against an unconfirmed version says that it may already be patched. Zero matched CVEs reports as healthy — never as an invented problem.
It feeds your Trust Score
VulnControl findings roll into the platform's overall Trust Score alongside everything else, so a serious exposure moves the number your dashboard opens with rather than sitting in a separate silo you have to remember to visit.
In-app, not in your inbox
Vulnerability findings notify in the platform and do not email. That's the same principle as the exploitation ranking itself: separating your to-do list from "this is being attacked now" is worth nothing if the backlog emails you anyway.
What VulnControl does not and cannot see
Stated here rather than discovered later. A buyer who finds a limit on their own stops trusting everything else on the page — and in a security tool, that mistrust is the correct response.
External observation only
It identifies what software announces about itself and what open ports reveal. Software that announces nothing, and anything not exposed to the internet, is invisible to it. For the inside view — your own code and the packages it depends on — see how CodeControl reads a repository
A curated product list, not all of NVD
39 widely-used products: CMS and e-commerce platforms, web and application servers, runtimes, remote-admin tools, databases, mail servers and the common JavaScript libraries. Something obscure isn't covered, and the report doesn't pretend otherwise. One framework is deliberately omitted because the vulnerability database has no usable identifier for it, so a mapping would only ever return nothing.
"Vulnerable" means the version has a published flaw
Not that the site has been broken into, and not always that the flaw is reachable in practice — some vulnerabilities require configurations you don't use. It reports what is knowable from outside, which is also what an attacker sees before they decide whether you're worth their time.
Distribution back-ports are invisible
Version comparison is numeric, so a distribution's patched build compares equal to the upstream version it was built from. A Debian or Ubuntu package can carry the fix while still reporting the old number. That's why an unconfirmed match says so in its own description rather than asserting you're vulnerable.
Vaguely-specified CVEs are skipped
A vulnerability record claiming to affect every version ever released is treated as incomplete data rather than as a claim, and pre-release-only records are skipped rather than matched against general-availability versions. Both decisions trade a little recall for precision, and both mean some real-but-vaguely-documented flaws won't appear.
A gap we'd rather name than hide
Full scans run fortnightly. If a flaw in software you run starts being exploited tomorrow, it's the next scheduled scan that notices — up to two weeks. You can trigger a scan by hand in the meantime, and this is known work: CodeControl already solves exactly this with a nightly re-check against the stored inventory, and the same approach belongs here.
WordPress plugin flaws are under-covered
We enumerate your plugins and themes, but the national database covers plugin vulnerabilities poorly, so matches there are thinner than for core software. A dedicated plugin-vulnerability feed is the known fix and isn't built yet.
Not a penetration test
It does not attempt to exploit anything, log in anywhere, or send malicious input. If you need someone to actively try to break in, that's a different engagement with a different risk profile — and it should be done by people, with a contract.
Compare it against the scanner you run today
If you already run an external scanner, the useful comparison is attribution accuracy: how many of its critical findings are actually yours, and whether it tells you when it couldn't establish a version.