Vulnerability-Lookup 6.2.0 released
We are pleased to announce the release of Vulnerability-Lookup 6.2.0!
This release is centred on the KEV catalogs. A producer can now withdraw one of its own assertions, as GCVE BCP-07 2.3 specifies, and the withdrawal propagates to the mirrors instead of vanishing. The KEV catalogs page gains three cards that read what the listings rest on: the evidence behind them, the profile of the vulnerabilities they list, and their weekly trends. An organization page now tells what an organization is affected by, published as a GNA and assigned as a CNA, and the dashboard gets an Other sources tab covering every feed outside the CVE and GCVE programs. Also in this release: similarity searches over the ATT&CK bi-encoder, a Prometheus endpoint, the amended GCVE-BCP-05 identifier placement, BCP-03 static feeds, a site notice, three new OSV sources and a generated OpenAPI snapshot.
Upgrade notes
- This release requires four PostgreSQL migrations (
poetry run flask --app website.app db upgrade). One of them is not optional for instances serving the pub/sub stream: it grants the newstream:subscribepermission to every role holding admin access, whichseed-rbacalone would not do. - The Kvrocks CISA and CNW known-exploited feeders are retired (see Changes): drop their
[feeder:cisa_known_exploited]and[feeder:cnw_known_exploited]sections fromconfig/modules.cfgand runtools/purge_kvrocks_kev_feeders.pyto delete their keys. - Instances publishing as a GNA should run
poetry run backfill_gcve_vulnidonce to complete their stored records with the amended GCVE-BCP-05 identifier placement (seedocs/update.md), and oneindex_vulnerabilities --source <local instance>pass to backfill the published index. - Instances importing FSTEC should run
tools/fix_fstec_alias_links.py --yesto repair the alias links written before the comma fix. - pyvulnerabilitylookup >= 4.5.0 is now required.
- The VARIoT feeder is disabled in the sample configuration, the service being unreachable.
What’s New
Withdrawn KEV assertions (GCVE BCP-07 2.3)
A producer can now take back its own assertion: an entry with status_reason: withdrawn and exploited: false is kept as a tombstone rather than deleted, so mirrors discover the withdrawal instead of carrying a listing its producer no longer stands behind.
Every exploited: false record is left out of the current KEV set: catalog pages, counts, the activity grid, coverage statistics, search badges and the API listing filter on it. The list endpoint’s exploited filter becomes true (the default), false or all, and the remote sync asks for all so an upstream withdrawal reaches the mirrors. The catalog page gets a “Show withdrawn” toggle; the entry page and the vulnerability header render a withdrawn entry as a muted tombstone pill with the withdrawal date instead of a red “listed as exploited” badge. The exploited sighting an entry carries is created only for asserted entries and removed on withdrawal.

A withdrawn assertion: CISA removed CVE-2026-69836 from its catalog after Microsoft corrected the advisory to not exploited. The entry stays as a tombstone, out of the current KEV set.
Administrators can withdraw an entry of any catalog from its page, while the edit form stays confined to the local catalog, which now has an edit button on the entry page. The shipped BCP-07 schema is refreshed and enforces the invariant on POST and PUT.
KEV catalogs page: evidence, profile and trends
Three new cards on /kev-catalogs read what the listings rest on. They are the subject of last week’s post, What Do KEV Catalogs Actually Know?, which walks through what they show on the public instance.
- Evidence behind the listings — per catalog, the mix of BCP-07 evidence types (first-hand observation or reports) with the mean confidence and the share of entries without evidence; per vulnerability, the strongest signal any catalog attaches and whether observation and reports corroborate each other, which no single catalog can tell.
- Profile of the listed vulnerabilities — the age of a CVE when each catalog picks it up, how many entries preceded publication, the median days from publication to first listing by publication year, and the EPSS bands and critical CVSS share of each catalog’s entries today.
- Weekly trends — the last 26 weeks as five small multiples (new listings per catalog, pre-publication listings, median lead time, evidence types, which catalog listed first), with configurable event markers drawn as a dashed line on every panel. The sample
KEV_EVENT_MARKERScarries the CRA Article 14 reporting obligation applying from 2026-09-11, the question this card is built to answer.

Evidence behind the listings: each catalog’s bar is split by evidence type; below, the strongest signal any catalog attaches to each vulnerability, and whether observation and reports corroborate each other.

The profile of the listed vulnerabilities: age at listing per catalog, time to first listing by CVE publication year, and where each catalog’s entries fall on today’s EPSS scale.
The corroboration buckets and the pre-publication and low-EPSS sets filter the coverage table through new evidence and focus parameters. Everything is computed from one Kvrocks pass and cached for an hour.
What an organization published and assigned
An organization page now carries the three relations it can have to a vulnerability as independently paged tabs: affecting the CPE names of its products, published as a GNA (from the GNA index) and assigned as a CNA (from a new, administrator-set cna_short_name column, never derived from the name).

The CIRCL organization page: the vulnerabilities affecting its products, the ones it published as GNA-1 and the ones it assigned as a CNA, each with its own feed. The first record carries the new GCVE extensions row.
Each list gets its Atom/RSS feed at /organization/<uuid>/recent.<format>?tab=..., and a product page advertises its own vulnerabilities as a feed at /product/<uuid>/recent.<format>. The organization, organizations and product views share one grammar and only render the facts a record carries, so a GNA-only organization is a compact card rather than an empty product grid.
The Other sources tab
The dashboard tabs are reorganised. The Activity tab is gone: its Comments, Bundles and Sightings lists duplicated the Community pages and its KEV entries the KEV Catalogs page. What was only visible there gets a proper place instead.
- An Other sources tab shows the latest records of every feed outside the CVE and GCVE programs (GitHub, PySec, OSV, national databases, CSAF providers…) as per-source cards grouped like the recent vulnerabilities page, with a toolbar to narrow the cards by group or by name. The CVE Program mirrors are covered by the CNA Roots tab and the GNA feeds by the new GNAs tab.
- A Ghost CVEs tab lists the identifiers sighted in the wild but absent from the CVE registries, one row per identifier with its recent sightings, the sites that sighted it and its last sighting. This replaces the former switch of the Vulnerabilities list and the “Unpublished advisories” option of the Trending tab.
- A GNAs tab covers the GCVE side the way the CNA Roots tab covers the CVE Program: a card per feed (this instance’s own GNA first, then the pulled ones) with the five latest publications, and a filterable table of every GNA in the signature-verified registry copy with its services and publication counts (#620).

The Other sources tab narrowed to the national vulnerability databases: one card per source with its latest records and feeds.

The same tab narrowed to the OSV sources, with the three feeds added in this release: BellSoft, Homebrew and openEuler.
Dashboard tabs can be linked to with a URL hash (/#tab-ghost, /#tab-other-sources, …).
Retrieval with the ATT&CK bi-encoder
Two similarity searches over the CIRCL/vulnerability-attack-technique-biencoder space served by ML-Gateway, which owns the vectors and the search, so no ML dependency is added to Vulnerability-Lookup. GET /api/vlai/attack-techniques/<technique_id>/vulnerabilities ranks the indexed vulnerabilities for one MITRE ATT&CK technique, and GET /api/vlai/related/<vulnerability_id> lists the vulnerabilities nearest to one record, searching on its stored vector or, when it is not indexed yet, on its description. Both are labelled as similarity searches, not classifications: the classification head remains the default for CVE → technique suggestions.
The response says which of the two searches answered. A record already indexed is searched by its stored vector ("by": "id"); a record the indexer has not reached yet is searched by its description ("by": "text"), so a vulnerability published a minute ago gets an answer too:
$ curl -s https://vulnerability.circl.lu/api/vlai/related/CVE-2026-21822?top_k=1 | jq .query.indexed
true
$ curl -s https://vulnerability.circl.lu/api/vlai/related/CVE-2026-21822?top_k=1
{"results": [{"id": "CVE-2005-3639", "score": 0.8382}], "model": "CIRCL/vulnerability-attack-technique-biencoder", "model_revision": "fb2219fa308ef9b967374267363f9b834a775b17", "error": null, "query": {"id": "CVE-2026-21822", "by": "id", "indexed": true}}
$ curl -s https://vulnerability.circl.lu/api/vlai/related/CVE-2026-92056?top_k=1 | jq .query.indexed
false
$ curl -s https://vulnerability.circl.lu/api/vlai/related/CVE-2026-92056?top_k=1
{"results": [{"id": "CVE-2026-2789", "score": 0.9644}], "model": "CIRCL/vulnerability-attack-technique-biencoder", "model_revision": "fb2219fa308ef9b967374267363f9b834a775b17", "error": null, "query": {"id": "CVE-2026-92056", "by": "text", "indexed": false}}On the website, the vulnerability page gains a “Related by attack behaviour” block under the ATT&CK suggestions, a new /attack/technique/<technique_id> page, linked from every suggestion card, lists the vulnerabilities for a technique with an “outside the trained vocabulary” badge when the model was not trained on it, and a technique index at /attack/technique/ (navbar entry ATT&CK) is the entry point.

The Related by attack behaviour block: the vulnerabilities whose description is nearest to this one in the bi-encoder space, with their cosine similarity. The block says what it is, a similarity search with no measured accuracy.
A new index_attack_embeddings consumer of the vulnerability channel keeps the gateway index in step with the feeders (batched, retried with backoff, bounded, never blocking a feeder), started by poetry run start when ATTACK_EMBEDDING_INDEXER is true. Its batch size adapts to the gateway’s pace, halved on a read timeout and grown back after consecutive full batches, so a CPU-bound gateway is never re-sent the same oversized batch forever. The existing corpus is loaded on the gateway host from the dumps.

The new attack-embedding-indexer process reporting its heartbeat on the monitoring page, next to the full-text indexer.
Amended GCVE-BCP-05: identifier placement, AI provenance extensions and relationships
GCVE-BCP-05, amended in September 2026, puts a record’s identifier in the vulnId of its single recordType: advisory entry of containers.cna.x_gcve instead of the non-standard cveMetadata.vulnId. This release is the compatible half of the migration: every reader (CNA API, GNA service, reindexers, full-text indexer, gcve_vl feeder, Vulnogram) accepts both placements, writers emit the new one and keep the legacy field, the GNA service refuses a record naming two different identifiers, and the dashboard’s GNA cards count the records a remote GNA still publishes in the legacy shape, so the deprecation can be timed on data. poetry run backfill_gcve_vulnid completes the stored records without bumping dates, rescoring indexes or notifying anyone.
The record view renders the BCP-05 extensions GNAs now push in a folded GCVE extensions panel: BCP-05-X-01 AI annotations (level, review status, models table) and BCP-05-X-02 patch2vuln provenance (generator, patches, rationales, model comparison), any other extension key falling back to JSON. The Relationships row groups relationships under the x_gcve entry that states them, with the type as a badge carrying the BCP-05 verb definition, and GCVE records assigned by this instance’s own GNA get a “This instance” pill.

The GCVE extensions panel on a record published by GNA-1: the AI involvement annotation and the patch2vuln provenance, from the generating model down to the CVSS rationale. The assigner row carries the new This instance pill.
The gcve_vl feeder now tops the BCP-03 static feed up from the publication API on every run, newest first until a whole page is already indexed, so a publication reaches peers without waiting for the next dump (#631).
And more
Prometheus endpoint — An opt-in
/metricsendpoint exposes Kvrocks memory, disk and RocksDB estimates, whether the derived state indexes still account for the corpus, EUVD identifier integrity, per-source ingestion freshness with the staleness threshold itself, and a request duration histogram and counter aggregated across gunicorn workers. Documented indocs/metrics.md. Contributed by @archakisn in #615 and #630.Correlations through x_gcve relationships — The relationships a GCVE record states now feed the “Related vulnerabilities” tab, both ways and for every relationship type (#638).
GCVE BCP-03 static feeds — The
gcve_vlfeeder reads a GNA’s complete published history from its BCP-03 static feed, falling back to the pull API when the feed cannot be read, with conditional fetches and eager validation of the first record. A GNA that publishes only a dump directory, as VULNARCHIVE does, is now pulled from it. Contributed by @adulau in #619, with #632.Site notice — An administrator can announce maintenance or an incident from
/admin/banner; the notice is rendered on every page and served byGET /api/banner, withPUT /api/bannerfor automation. Contributed by @archakisn in #605.EUVD analytics figures — The EUVD statistics surfaces read prepared figures instead of recomputing them per visitor, and the “first listed as exploited” date rule is unified on the KEV entry model as
listed_at, so the KEV timeline and the EUVD exploited dates agree. Contributed by @archakisn in #626.BCP-07 KEV export — The known-exploited export in
dumps/is the GCVE BCP-07 serializationGET /api/kevreturns, one record per assertion with its origin, evidence and status, ordered so two runs over unchanged data are byte-identical. Every dump is now written to a temporary file and renamed over the destination. Contributed by @archakisn in #604.Three OSV sources — The Homebrew advisory database, the openEuler security advisories and the BellSoft OSV database (#645, #646, #652).
Withdrawn advisories — A source that retracts an advisory (GitHub withdraws a few percent of its advisories; the OSV feeds carry a
withdrawntimestamp) is now marked wherever the record is drawn: its own page, the related-advisory lists, the/recentrows and the feeds, where an entry titles itself “Withdrawn:” since a withdrawal bumps modifiedand would otherwise arrive at the top as news. The marker matches the KEV tombstones. Contributed by @archakisn in #636.
Two withdrawn BellSoft advisories on the recent vulnerabilities page: the tombstone badge under the identifier tells why they were updated.
Generated OpenAPI snapshot —
flask --app website.app dump_openapirenders the API reference straight from the API object, a new workflow checks the snapshot on every pull request, and a pre-commit hook regenerates it (#643).Search — An empty search form lists the selected sources’ entries newest first instead of returning the bare form.
EUVD records minted by the allocator are rendered as what they are, an alias whose description, severity and references belong to the linked CVE (#644).
Changes
Feeders — The Kvrocks CISA and CNW KEV feeders are retired.
cisa_known_exploitedandcnw_known_exploitedmirrored the two lists outside the BCP-07 model, append-only and keyed by meta uuid, so retractions stayed forever and re-minted uuids produced duplicates. The same lists are imported as BCP-07 catalogs by gcve-eu-kev, which reconciles retractions, so the feeders, their/api/cisa_kev/and/api/cnw_kev/endpoints (served by/api/kev/filtered onvulnerability_lookup_origin) and their storage accessors are removed; the classic/known-exploited-vulnerabilities.{atom,rss}feed redirects permanently to/kev-catalogs/feed.{format}. pyvulnerabilitylookup 4.5.0 is the client release that stops calling the removed endpoint (#640, #641).Feeders — The VARIoT feeder and source are disabled in the sample configuration, the service being unreachable.
Vulnerability page — A vulnerability description is rendered with its own line structure (about one CVE in five wraps its lines, and advisories built from mailing-list posts carry headings and numbered steps), with bare http(s) URLs linked. Applied to the CVE 5 and FKIE NVD summaries.
Website — The FSTEC card is rebuilt on the model of the CVE one: ISO dates, a link to the BDU record, status and KEV badges, severity chips with score, rating and calculator link for CVSS 2.0/3.x/4.0, linked CWEs, aliases linked to their records, collapsible references and impacted products, mitigations and credits, closed-vocabulary values translated.

The rebuilt FSTEC card: the BDU record rendered like a CVE one, with its closed-vocabulary fields translated and its alias linked.
Website — The generic OSV card, shared by the eleven OSV-format sources, gets the header of the CVE one (icon badge, first upstream id, source and dates, withdrawn / VLAI / KEV badges) and the VLAI severity classification.
Notifications — Each scheduler cycle takes at most ten due notifications, longest-waiting first, and a run that started late is re-anchored, so the population due after a downtime drains over a few cycles instead of landing again in the same few minutes one interval later.
Configuration — Every source of
SOURCES_TO_SHOWwhose identity is unambiguous has a one-line description.Lint — The ruff rule set is pinned in
pyproject.toml, and the code base uses PEP 585 builtins andcollections.abcinstead of the deprecated typing aliases.Dependencies — Updated Python and GitHub Actions dependencies, including alembic.
Changelog
📂 For the full list of changes, including the fixes, check the GitHub release:
https://github.com/vulnerability-lookup/vulnerability-lookup/releases/tag/v6.2.0
🙏 A big thank you to all contributors and testers!
Feedback and Support
If you encounter any issues or have suggestions, feel free to open a ticket on our GitHub repository:
https://github.com/vulnerability-lookup/vulnerability-lookup/issues/
Your feedback is always appreciated!
Follow Us on Fediverse/Mastodon
You can follow us on Mastodon and get real-time information about security advisories:
https://social.circl.lu/@vulnerability_lookup/