Open-source CVE monitoring: four designs and where each one breaks
Of the 9,770 CVE records published in July 2026, 4,884 carry no machine-readable list of affected products. A subscription to “nginx” or “Fortinet” cannot fire on those records — not because the tool is poor, but because the record holds nothing for it to match against. So the first decision when you build CVE monitoring from free parts is not which tool to install. It is which design you are building.
Four designs, not forty tools
| Design | How it learns what you run | Representative |
|---|---|---|
| Raw authority feed | it does not — you do the matching | NVD, CISA KEV, BSI WID, ENISA EUVD |
| Vendor and product subscription | you maintain the list by hand | OpenCVE |
| Scanner on the artefact | it reads binaries, SBOMs, lockfiles | cve-bin-tool, Trivy, Grype |
| Inventory held by the service | you submit it once, it is re-evaluated continuously | Dependency-Track |
Everything else is a variation. The design decides more than the product does: a scanner cannot watch an appliance it never touches, and a subscription cannot know about a library you forgot you shipped.
Design one: the raw authority feed
Free, no account, no licence question, machine-readable — and no idea who you are.
- CISA KEV — one JSON file, 1,670 entries in catalogue version 2026.08.18. Three conditions for entry: an assigned CVE ID, “reliable evidence that the vulnerability has been actively exploited in the wild”, and a clear remediation action.
- NVD API 2.0 — 362,257 CVE records on 19/08/2026, withdrawn ones excluded. Five requests per rolling 30 seconds without a key, fifty with one; the documentation suggests sleeping six seconds between calls.
- BSI CERT-Bund WID — German-language advisories as RSS, severity in the title and as a category.
- ENISA EUVD — the European database, with its own identifiers and its own API. The NIS2 Directive tasks ENISA with maintaining it.
The break is repetition without relevance. The BSI feed has no product filter. On 19/08/2026 its RSS feed held 250 items, 204 of them marked [UPDATE] — revisions of advisories you had already read. Four out of five notifications are re-runs, and not one of them is filtered to your estate. A raw feed is a building block, not a service: you still have to write the part that decides whether an entry concerns you.
Design two: subscribe to vendors and products
OpenCVE is the reference implementation. Its own documentation puts it plainly: subscribe to vendors and products to follow the technologies you use. It cross-references MITRE, Vulnrichment, the NVD and Red Hat, notifies by email, webhook or Slack, groups subscriptions into organisations and projects, and runs on your own server via Docker. For a team that knows its estate, this is the shortest path from “a CVE appeared” to “someone was told”.
The first break is the licence. OpenCVE ships under the Business Source License 1.1, which is not an OSI-approved open-source licence. It converts to Apache 2.0 on the change date of 14 August 2030. Until then the additional use grant reads, word for word, that you may use the work “provided that you do not use the Licensed Work for a Security Monitoring and Alerting Service” — and the file does not define what falls under that phrase. Read it yourself before you build anything on top of it.
The second break is the matching. A product subscription can only fire when the record says which product is affected — and that is exactly the field half of them are missing. The section on shared limits explains why.
Why keyword subscriptions produce false alarms
The convenient shortcut is to subscribe to a word instead of an identifier. Measure what that costs. Three queries against the NVD API on 19/08/2026, for one of the most common pieces of infrastructure there is: keywordSearch=nginx returns 369 records. virtualMatchString=cpe:2.3:a:f5:nginx returns 41. cpe:2.3:a:nginx:nginx returns 2.
Two lessons sit in those numbers. The word returns roughly eight times as many hits as both identifiers together, and the extra records are not hidden flaws — they are entries where nginx appears as scenery: the reverse proxy in front of the actually vulnerable application, a layer in a container image, a step in an attack path. And the same product lives under two vendor strings, so subscribing to one of them silently loses the other. The counter-example matters too: keywordSearch=zabbix returns 99 against 96 for the identifier. With an unambiguous name the difference nearly vanishes. The false-alarm rate is a property of the name, not of the tool.
Vendor-level subscriptions overshoot. In July 2026 the records filed under the CPE vendor string apachespread across 40 distinct products — Tomcat, Log4j, Camel, Superset, Thrift, several Airflow providers. Subscribe to “Apache” and you have subscribed to all forty.
Version numbers lie. Red Hat states the problem for its own packages: some tools “make decisions about vulnerabilities based solely on the version number of components they find. This results in false positives as the tools do not take into account backported security fixes.” Backporting a fix without bumping the version is what Debian, Red Hat and SUSE do all day.
Design three: scan the artefact
cve-bin-tool (GPL-3.0, started at Intel, now under the OpenSSF) inverts the question. Instead of asking what you run, it reads it out of the thing itself. cve-bin-tool <directory> walks binaries looking for library signatures and version numbers; cve-bin-tool --sbom cyclonedx --sbom-file bom.jsontakes an SBOM instead, in SPDX, CycloneDX or SWID. It carries 448 checkers and pulls data from the NVD, Red Hat, OSV, the GitLab Advisory Database and curl. An NVD API key is optional; by default it reads from the project’s own mirror.
The break is that it only sees signatures and version numbers. The project says so itself: it “cannot tell if someone has backported fixes to a vulnerable version, and it will not work if library or version information was intentionally obfuscated”, and it “does not guarantee that any vulnerabilities reported are actually present or exploitable, neither is it able to find all present vulnerabilities with a guarantee”. A component without a checker is invisible. And a scan is a snapshot: it answers today’s question, not next week’s.
Design four: the service holds your inventory
OWASP Dependency-Track (Apache-2.0) fixes the snapshot problem. You submit a CycloneDX SBOM once; the platform “monitors component usage across all versions of every application in its portfolio” and re-evaluates it against the NVD, GitHub Advisories, OSV, OSS Index and others. When a new flaw lands, no new scan is needed — the inventory is already there.
The break is the inventory itself. What was never submitted does not exist for the service, and that is most of an ordinary estate: firewalls, hypervisors, NAS boxes, phone systems and printers ship no SBOM. Add another database and another service to patch, and this design fits software you build far better than software you merely operate.
The limit all four share
On 15 April 2026 the NVD changed how it works, and every tool downstream inherited the change. Submissions rose 263 percent between 2020 and 2025. The NVD enriched nearly 42,000 CVEs in 2025, 45 percent more than in any earlier year, and still could not keep up. Since that date three groups are prioritised for enrichment: CVEs in the CISA KEV catalogue, with a stated goal of one business day; CVEs for software used in the US federal government; and critical software as defined by Executive Order 14028. Everything else is filed as “Lowest Priority — not scheduled for immediate enrichment”, and the entire backlog published before 1 March 2026 was moved to “Not Scheduled”.
Enrichment is the step that produces CPE product lists. Hence the number at the top: of 9,770 records published in July 2026, 4,886 carried a product list and 4,884 did not — and the missing ones sit exactly where the enrichment has not run. Every record marked “Deferred”, “Awaiting Analysis” or “Received” had none — 4,800 of them — and the remaining 84 were still “Undergoing Analysis”. “Deferred” officially means “not currently scheduled for NVD enrichment efforts”. June 2026 was marginally better at 4,318 of 7,943. CISA’s Vulnrichment does not fill the gap: as of 10 December 2024 it “will no longer be adding CPE strings to the enriched dataset”. Two things follow — the rule that no alert does not mean no vulnerability, and the observation that the only lane with a service level still attached to it is evidence of exploitation.
Where patchletter sits in this table
patchletter is the fourth design in its narrowest form: you tick the products you operate and the service holds that list — its regular job is to tell you when one of them puts out a new release. For the CVE question it checks the same list against the KEV catalogue every day, which means against proven exploitation and nothing wider. The boundaries belong before the benefits. It is not a scanner — it never sees your binaries, so it will not find the library you forgot. It is not an inventory — it knows only what you ticked. And it is deliberately not a complete CVE feed: the CVE page mirrors the KEV catalogue against tracked products, which is proven exploitation and therefore a floor, not a ceiling.
If you are building rather than subscribing, the more useful door is the public REST API. /api/v1/products/{slug}/cvesreturns one product’s hits with a knownExploited flag, a ransomware marker and the CISA due date; /api/v1/cves does the same across every tracked product; /api/v1/openapi.json is the machine-readable spec. Read access needs no account and no key. Between a raw feed and a scanner you have to host somewhere, that is the layer the table above is otherwise missing.
The honest limitation
None of the four designs answers the question that actually matters: are you exploitable? That depends on your version, your configuration, whether the module is loaded and whether the port is reachable — and no feed knows any of it. Nor is the KEV catalogue a measure of danger. 1,670 entries accumulated since November 2021 is a very short list, and it is short by design: three conditions have to be met before anything goes on it. What is on it is proven. What is missing is merely unproven.
All figures external, retrieved 19/08/2026. Monthly CVE volume, CPE coverage, the nginx and zabbix comparisons and the Apache product count: NVD API 2.0, queried with noRejected, keywordSearch and virtualMatchString, counted over the full month. Rate limits and status definitions: NVD developer and vulnerability-status pages. Prioritisation rules, the 263 percent figure and the enrichment numbers: NVD announcement of 15/04/2026. KEV count, catalogue version 2026.08.18 and the three inclusion criteria: CISA. CPE note: cisagov/vulnrichment README. Licence terms: opencve/opencve LICENSE. Checker count: ossf/cve-bin-tool README. Feed composition: BSI CERT-Bund WID RSS. Backporting quotation: Red Hat. No figure in this article comes from our own dataset.