Vulnerability-Lookup 6.1.0 released

We are pleased to announce the release of Vulnerability-Lookup 6.1.0!

This release brings a native EUVD API: an instance now exposes the EUVD identifiers it allocates through its own /api/euvd namespace, with listing, lookup by any correlated alias, advisory mapping, and a search endpoint that pages over the whole corpus. The CVE Program hierarchy arrives on the website as CNA roots — a root: search operator, a new dashboard tab and per-root feeds. A CPE-Editor instance can be plugged into the vulnerability page, the frontend libraries are now managed with npm, and administrators get an activity report of their local CNA/GNA over any date range. On top of that: sighting summaries on bundles, a Markdown export of the recent vulnerabilities, the CVE Program’s bundle warning, a storage fix that matters to every instance running on a modest host, and a batch of security fixes.

Upgrade notes

  • This release requires Node.js >= 18 and npm to install the frontend libraries (npm ci --omit=dev, run for you by poetry run update), a PostgreSQL migration (poetry run flask --app website.app db upgrade) and gcve >= 0.13.0.
  • The versioned kvrocks.conf no longer carries the production host’s tuning (see Fixes). Instances that customized the versioned file must move their settings to storage/kvrocks.local.conf before restarting.
  • Before enabling the EUVD feeder for the first time, run flask --app website.app index_health and reindex if it reports the derived indexes behind the source index.

What’s New

Native EUVD API

A new /api/euvd namespace exposes the EUVD identifiers an instance allocates, backed by the linked CVE records rather than by a second copy of the data. This is part of an ongoing development in close collaboration with ENISA, and the feature is not enabled by default in Vulnerability-Lookup. Contributed by @archakisn in #555, #556, #557, #558, #570 and #573.

  • GET /api/euvd/ lists the latest entries, filtered on coordinated assigners, CVSS and EPSS bounds, KEV catalog membership and exploitation status.
  • GET /api/euvd/<identifier> answers a single entry from an EUVD id, a CVE id or any correlated alias (GHSA, PYSEC, GSD, MAL).
  • GET /api/euvd/advisory/<id> maps a stored CSAF advisory to the EUVD entries it covers.

The endpoints started as a byte-compatible replacement for the ENISA service’s homepage feeds and were reshaped into Vulnerability-Lookup’s own API during review. Advisory display labels are recorded when a link is written, and invalidated by the CSAF feeders when the advisory is rewritten; a euvd --backfill-advisory-labels command covers links made before that. The full CVE/EUVD mapping is also published as an open-data export in dumps/.

EUVD search

GET /api/euvd/search pages over the whole filtered corpus and reports how many entries match, which the bounded listing deliberately cannot (#568, #569, #595, #598, also by @archakisn).

Vendor and product match by prefix and assigner exactly, as the ENISA service does, with vendor_contains and product_contains for substrings. Publication and update date ranges apply at the same time, exploitation can be bounded by first-listing date, and free text (?text=) is answered from the Meilisearch full-text index rather than by scanning records — an instance without the index refuses with 503 instead of a confident empty answer. The walk is bounded in every dimension (a filter that names an entity drives the walk from its own set), and the response says whether count is a total or a floor through count_is_exact. A euvd --backfill-vendor-name-space pass registers vendors linked before the name space was maintained, since the prefix driver reads it as complete.

CNA roots

The CNA partner catalogue — fetched through the gcve client, refreshable from the admin maintenance page, with a bundled snapshot as fallback — now carries the CVE Program hierarchy (#565, #567).

  • The assigner search accepts root:<name> to select every CNA under a root, materialized server-side.
  • The vulnerability page shows the assigner’s root next to its name.
  • A fourth CNA Roots dashboard tab lists the ten latest vulnerabilities of each root with their titles and impacted vendors/products, draws the Program structure with the CNAs folded under each root, and offers per-root RSS/Atom feeds at /cna-root/<root>/recent.<format>.
The CNA Roots dashboard tab: the CVE Program structure with CISA and mitre as top-level roots, their CNA-LRs and CNAs folded underneath, and below it the latest vulnerabilities published under the CISA, ENISA and Google roots with RSS and Atom icons

The new CNA Roots dashboard tab: the CVE Program structure, rendered live from the CNA partner catalogue, and the latest vulnerabilities published under each root.

CPE Editor integration

A CPE-Editor instance, such as cpe.gcve.eu, the collaborative catalogue of vendors, products, CPEs and PURLs run by GCVE, can be plugged into the vulnerability page: the CPE names of a record are checked against the editor’s catalogue, and missing vendors or products can be proposed from a pre-filled form that hands over to the editor. CPE 2.2 and 2.3 names are parsed with their escaping preserved and cpeApplicability semantics honored. The integration is disabled by default and configured in config/cpe.json. Contributed by @NMD03 in #564.

The vulnerability page for CVE-2026-81827 with a CPE status column in the impacted products table, showing a guessed CPE and a green Guessed CPE found in catalog badge; the assigner CIRCL carries an ENISA root badge

A record without a CPE name: the guess constructed from the vendor and product matches an entry of the CPE Editor catalogue. Note the assigner’s root, shown next to its name since this release.

The vulnerability page for CVE-2026-56651 showing the CPE name cpe:2.3:a:scottchiefbaker:dool with a Not in catalog badge and the tooltip Not found in the CPE Editor catalog, click to propose it

A CPE name absent from the catalogue: the badge links to a proposal.

The CPE Editor Submit a proposal form opened from the vulnerability page, pre-filled with the proposal type Add a new vendor and product, the vendor token scottchiefbaker and the product token dool

The hand-over to the CPE Editor: the proposal form arrives pre-filled with the vendor and product parsed from the CPE name.

Frontend libraries managed with npm

The third-party JavaScript and CSS libraries (Bootstrap, chart.js, d3, luxon, easymde, choices.js, cal-heatmap, flatpickr, showdown, the JSON editor, …) are no longer vendored. They are pinned in package.json, installed with npm ci --omit=dev and copied to static/npm_components by a postinstall script, which update runs. Bootstrap is served from npm instead of Bootstrap-Flask, so its version no longer follows the Python dependencies. Node.js >= 18 is enough, as nothing executes Node at runtime, and dependabot now watches the npm ecosystem too.

Activity report

/admin/activity-report summarizes the local CNA/GNA activity over a UTC date range — identifier reservations, publications, local KEV entries and evidence, comments, bundles, sightings, disclosures and user registrations — as summary cards, two grouped charts with log-scale and cumulative toggles, the CNA publication workflow table, and a Markdown download (#574). Events are counted by UTC day and by when they happened (reservations are now scored by reservation time), so a past period’s report is reproducible. The DB migration indexes the scanned timestamps.

The admin activity report for gna-1 from 2026-08-04 through 2026-09-02, with a UTC date range form, a Download Markdown button and summary cards for vulnerability assignments, published vulnerabilities, local KEV entries, KEV evidence, comments, bundles, sightings, disclosures and user registrations

The activity report: a UTC date range, summary cards for the period, and a Markdown download.

Two charts of the activity report: Publications and advisories, cumulative, with vulnerability assignments and published vulnerabilities rising over August, and Community activity with daily user registrations, comments, bundles and sightings

The two grouped charts, each with log-scale and cumulative toggles.

Sighting summaries on bundles

The bundle list and the bundle page summarize the sightings of a bundle’s vulnerabilities per type, counted once per vulnerability, case-insensitively (#572). The eight sighting types and their labels now have a single source of truth shared by the model, the forms, the API and the templates. The DB migration adds the functional index the aggregation runs on.

The recent bundles list showing a Cisco Crosswork Security Hardening Release bundle with a Sightings summary line: 40 total, Published Proof of Concept 6, Seen 34

A bundle in the list with its sightings summarized per type.

Markdown export of recent vulnerabilities

/recent/<source>.md exports the page on screen as Markdown for notes and tickets (#607): ?mode=index lists the identifiers as links, ?mode=full also embeds each stored record, bounded to 8 MiB per page. The export is cached and rate-limited like the feeds, and documented in docs/feeds.md.

A terminal running curl -s https://vulnerability.circl.lu/recent/cvelistv5.md piped into glow, rendering a Recent vulnerabilities from CVE Program heading and a bulleted list of CVE identifiers, each linked to its vulnerability page

The recent CVE Program vulnerabilities fetched as Markdown and rendered in a terminal with glow.

CVE Program bundle warning

When the CVE Program’s ADP flags references as bundled, the vulnerability page shows the Program’s own notice in a dedicated warning, with the flagged links listed separately from the standard references (#608, #609, #610). The rerouting is gated on the provider identity, so a third-party ADP carrying the tag is never attributed to the Program, and a malformed record degrades instead of failing the page. The five divergent rules for picking an English description are replaced by one shared picker.

The vulnerability page for CVE-2026-20359, Cisco Crosswork Security Hardening Release: August 2026, with a yellow CVE Program bundle warning above the title quoting the Program notice that a single CVE ID was assigned to a collection of individual vulnerabilities, and linking to the Program blog post

A record flagged by the CVE Program: the Program’s own notice is shown above the record, with the link to its blog post.

KEV publication activity

The KEV catalog page shows a GitHub-style contribution grid of how many vulnerabilities the catalog listed per day, by its earliest observation date, from a single grouped query (#575). Selecting a day filters the entries below.

The Shadowserver KEV catalog page with a new Publication activity panel: a contribution grid of the last 12 months with year buttons, reading 280 vulnerabilities listed on 126 days, busiest day 10, above the list of KEV entries

The publication activity grid on a KEV catalog page.

Titles in the credit listings

The credit listings show the title of each vulnerability, resolved through a shared extractor for CVE 5 and CSAF records and memoized in the cache, so the page no longer parses full advisories on every hit (#593). The disclosures list now links each credit to the credits page as well.

The Vulnerability Credits page listing 27962 credited people and organizations ranked by number of advisories, WPScan first with 3350, with a search field and a sort toggle

The credits index, ranked by number of advisories.

The statistics page with the Top 10 Credits chart for September 2026 next to the Top 10 Most Common CWE chart, with a Browse vulnerability credits button

The monthly credits ranking on the statistics page.

And more

  • A new flask --app website.app index_health command reports whether the derived state indexes account for the source index and exits non-zero when they are behind (#596, #602). A stale instance is otherwise invisible, while the EUVD creation pipeline and the mapping export silently under-produce on it.

Changes

  • API — The rate-limit prose of /.well-known/api-policy.json is derived from the configured limits, so it can no longer advertise “no enforced rate limits” next to an enforced limits block; RATE_LIMITS_POLICY remains an optional override (#603).
  • Website — The vulnerability disclosures list links each credit to the credits page and shows identifiers in uppercase.
  • Documentation — Updated the hardware and memory requirements, recommended restricting network access to Kvrocks, and documented the Node.js/npm prerequisite.
  • CI — Ruff is a real gate in CI and in the pre-commit hook, both with --no-fix; the test jobs are capped so a hang fails instead of pending, a hung test dumps where it hangs, and the fixture teardown no longer deadlocks on the notify session or the KEV digest worker (#584, #587, #591, #592).
  • Dependencies — Updated Python, JavaScript and GitHub Actions dependencies, including the gcve client and cryptography.

Security

  • showdown is installed from its 3.0.0-rc2 git tag: the latest npm release (2.1.0) is affected by three unfixed advisories (GHSA-cr32-g25g-vxjj, GHSA-22g5-r2x5-97cx, GHSA-rmmh-p597-ppvv) and upstream only ships the fixes in tags.
  • The comment, sighting and role-assignment delete views only redirect to same-host relative referrers, and reject backslashes, which browsers normalize into a protocol-relative redirect (open redirect).
  • The CNA publication views catch a dedicated PublicationError instead of any ValueError, so incidental error messages from deeper code no longer reach HTTP responses.
  • API 404s no longer suggest “did you mean” routes drawn from the whole route table, which leaked admin URL patterns before any authorization check (#586).

Fixes

  • Storage — The versioned kvrocks.conf shipped the production host’s tuning (a 128 GB block cache among others) to every instance since 4.6.0, exhausting RAM and swap on modest hosts during imports. Default tuning is restored and instance-specific settings go in storage/kvrocks.local.conf; operators who tuned the versioned file must move their settings there before restarting (#566).
  • Full-text — The full-text index buffer is bounded under Meilisearch backpressure instead of growing without limit while the queue is backlogged.
  • Feeders — The shared VEX import pipeline (redhat_vex, suse_vex, microsoft_vex) flushes by bytes, not only by document count, so multi-MB documents no longer buffer gigabytes in the importer.
  • API — Error bodies are no longer marshalled away: POST /api/user/api_key with a wrong key, and the bundle, comment, user and EUVD 4xx responses answered a literal {}; the self-registration refusals of POST /api/user/ now report under message like every other error (#577, #590).
  • EUVD?exploited=true on the listing refuses with 503 when the KEV scan cannot be resolved, instead of answering a confident empty result produced by an outage, and a failed scan is queried once per request rather than once per batch (#599, #601).
  • Update — The package stays importable with gcve < 0.13.0, so poetry run update can install the new dependency instead of crashing before it.
  • Website — Removed stray text after the loading spinner on the vulnerability page.

Changelog

📂 For the full list of changes, check the GitHub release:
https://github.com/vulnerability-lookup/vulnerability-lookup/releases/tag/v6.1.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/