Skip to content

CVEDB

The cvedb dataset is Shodan's SQLite vulnerability database, containing NVD vulnerability records and their affected-product (CPE) associations. It powers the public CVEDB API and vulnerability enrichment for the banners-daily and banners-hourly datasets.

Quickstart

  1. Download the database file:

    Terminal window
    shodan data download cvedb cvedb.sqlite.gz
  2. Uncompress it:

    Terminal window
    gunzip cvedb-cvedb.sqlite.gz
  3. Rename it to something more convenient:

    Terminal window
    mv cvedb-cvedb.sqlite cvedb.sqlite
  4. Use the sqlite3 tool to query it for test purposes:

    Terminal window
    sqlite3 cvedb.sqlite

The SQLite database is optimized for looking up vulnerabilities based on a CPE, and can also be queried by CVE identifier. Searchable CVE and CPE fields are stored in cveXcpe. Detailed CVE, EUVD, and GHSA source records are stored separately in cveXdata as gzip-compressed JSON blobs; decompress the relevant payload column before reading its JSON. The tables and indexes relevant to these lookups are:

CREATE TABLE IF NOT EXISTS "cveXcpe" (
cve_id VARCHAR NOT NULL,
cve_name VARCHAR(50),
euvd_name VARCHAR(50),
ghsa_name VARCHAR(50),
epss FLOAT,
kev BOOLEAN,
status BOOLEAN,
part VARCHAR(100),
vendor VARCHAR(100),
product VARCHAR(100),
version VARCHAR(100),
published_timestamp INTEGER,
PRIMARY KEY (cve_id)
);
CREATE TABLE IF NOT EXISTS "cveXdata" (
cve_name VARCHAR(50),
euvd_name VARCHAR(50),
ghsa_name VARCHAR(50),
compressed_cve_data BLOB,
compressed_euvd_data BLOB,
compressed_ghsa_data BLOB
);
CREATE INDEX kev_index ON "cveXcpe" (kev);
CREATE INDEX cve_name_index ON "cveXcpe" (cve_name);
CREATE INDEX euvd_name_index ON "cveXcpe" (euvd_name);
CREATE INDEX ghsa_name_index ON "cveXcpe" (ghsa_name);
CREATE INDEX epss_index ON "cveXcpe" (epss);
CREATE INDEX ix_cpe_composite ON "cveXcpe" (part, vendor, product, version);
CREATE INDEX published_timestamp ON "cveXcpe" (published_timestamp DESC);
CREATE INDEX product_index ON "cveXcpe" (product);

cveXcpe

The table is association-oriented: a CVE can have multiple rows when it applies to multiple CPE configurations. The API groups those rows when it returns one CVE record.

ColumnMeaning
cve_idCVE identifier field associated with the record.
cve_nameCVE identifier, for example CVE-2025-8960.
euvd_nameLinked European Union Vulnerability Database identifier, when available.
ghsa_nameLinked GitHub Security Advisory identifier, when available.
epssEPSS probability score, from 0 to 1, when available.
kevBoolean flag indicating whether the CVE is listed in the Known Exploited Vulnerabilities (KEV) data.
partCPE 2.3 part component, commonly a (application), o (operating system), or h (hardware).
vendorCPE vendor component.
productCPE product component.
versionCPE version component. Special values such as * or - may represent non-specific or unavailable values in source CPE data.
published_timestampCVE publication time represented as Unix epoch seconds.

The application creates indexes for cve_name, euvd_name, ghsa_name, epss, kev, product, vendor, descending published_timestamp, and the composite CPE components (part, vendor, product, version).

cveXdata

This table stores the detailed source records associated with the IDs in cveXcpe.

ColumnMeaning
cve_nameCVE identifier used to link the record to cveXcpe.cve_name.
euvd_nameEUVD identifier used to link the EUVD payload, when available.
ghsa_nameGHSA identifier used to link the GHSA payload, when available.
compressed_cve_dataGzip-compressed JSON with detailed CVE source data.
compressed_euvd_dataGzip-compressed JSON with detailed EUVD data, when available.
compressed_ghsa_dataGzip-compressed JSON with detailed GHSA data, when available.

The payload columns are binary gzip data, not plain text JSON. Decompress and UTF-8 decode a payload before parsing its JSON. The API performs this decoding and maps the source attributes into its response model.

Example queries

Look up a CVE

Look up a CVE's linked EUVD/GHSA identifiers, EPSS and KEV values, and all associated CPEs. The API groups multiple CPE association rows into one CVE record:

SELECT
cve_name,
euvd_name,
ghsa_name,
epss,
kev,
GROUP_CONCAT(
DISTINCT 'cpe:2.3:' || part || ':' || vendor || ':' || product || ':' || version
) AS cpes
FROM cveXcpe
WHERE cve_name = 'CVE-2014-0160'
GROUP BY cve_name;

Retrieve the source records for a CVE

Retrieve the compressed source records for that CVE. These BLOB values are gzip-compressed JSON; decompress and UTF-8 decode them in your application before parsing:

SELECT
cve_name,
euvd_name,
ghsa_name,
compressed_cve_data,
compressed_euvd_data,
compressed_ghsa_data
FROM cveXdata
WHERE cve_name = 'CVE-2014-0160';

Find CVEs linked to an EUVD

Find CVEs linked to an EUVD identifier:

SELECT DISTINCT cve_name, euvd_name, ghsa_name, epss, kev
FROM cveXcpe
WHERE euvd_name = 'EUVD-2024-16003';

Find CVEs linked to a GHSA

Find CVEs linked to a GHSA identifier:

SELECT DISTINCT cve_name, euvd_name, ghsa_name, epss, kev
FROM cveXcpe
WHERE ghsa_name = 'GHSA-wcwp-r3fj-mm3p';

Find CVEs by product and version

Find CVEs associated with a product version and check KEV status:

SELECT DISTINCT cve_name, kev, epss, published_timestamp
FROM cveXcpe
WHERE product = 'nginx' AND version = '0.1.0'
ORDER BY published_timestamp DESC;

Count CVEs for a product

Count unique CVEs associated with a product:

SELECT COUNT(DISTINCT cve_name) AS cve_count
FROM cveXcpe
WHERE product = 'nginx';

Because cveXcpe stores one row per affected-product/CPE association, the same CVE may appear in multiple rows. Use DISTINCT or COUNT(DISTINCT cve_name) when you need unique CVEs.