CVE correlation
Since 2.0, enodia can tell you which known vulnerabilities affect the exact version each target reports — alongside the patch/lifecycle/branch axes, not instead of them. It matches against two public databases:
- БДУ ФСТЭК — FSTEC’s (Russia’s) vulnerability database, bdu.fstec.ru.
- NIST NVD — the US National Vulnerability Database, nvd.nist.gov.
Either works alone; with both configured, their findings are merged per CVE.
Since 2.2, four vendors’ own security data joins them where they publish it: MariaDB, Atlassian (Jira, Confluence, Bitbucket, Bamboo), PostgreSQL and nginx — see Vendors’ own data.
Since 2.1, ten Linux distributions are also matched per installed package against their vendors’ own security data — the Debian Security Tracker, vendor OVAL files and Alpine’s secdb (see Package-level CVEs for Linux distributions).
It’s all opt-in: a config without a cve: block behaves exactly as 1.x
did, and each source works on its own.
Downloading the databases
Section titled “Downloading the databases”enodia matches against local files only. check, collect and serve
never download anything — the same closed-network reasoning as the
two-phase design: the
machine running check doesn’t need internet access for CVE matching,
only a copy of the files. Since 2.2, one separate command fetches them,
and only when you run it: enodia cve update. Or download them yourself,
as described per source below — the files are the same either way.
enodia cve update
Section titled “enodia cve update”enodia cve update # every cve.*.path in the active configenodia cve update --from inventory.jsonl # also what that inventory's hosts needenodia cve update --dry-run # list what would be fetched, download nothingInto each configured cve.*.path it fetches what that entry reads:
- БДУ —
vulxml.zip.cve.bdu.pathhas to be a.ziphere; the.xmland.tar.gzforms the lookup also accepts are your own repackaging, whichupdatedoesn’t produce. - NVD — this year’s file, last year’s, and any year not on disk yet;
--all-yearsrefreshes every year (NVD rebuilds all yearly files daily).cve.nvd.pathhas to be a directory. - Debian — the tracker’s
.json. - OVAL, Alpine secdb, PostgreSQL’s per-major pages — one file per
release, so the releases come from three places: files already in the
directory, the inventories given with
--from(whatever releases its hosts run), and--oval,--alpineand--postgresql.cve.oval.pathandcve.alpine.pathhave to be directories; acve.postgresql.paththat is a file gets the main page only. Since 2.2.1 an OVAL or Alpine directory with no release from any of the three is an error (exit status1) — name one or drop the key, sincecheckrefuses an empty directory anyway. - MariaDB, Atlassian, nginx and PostgreSQL’s main page — one file each.
| Flag | Fetches |
|---|---|
--from <inventory> |
the OVAL releases, Alpine branches and PostgreSQL majors that inventory’s hosts need (repeatable) |
--oval <release> |
one OVAL release: ubuntu:<codename>, rhel:<N>, almalinux:<N>, oracle-linux:<N>, astra-linux:<X.Y>, redos:<X.Y> (repeatable) |
--alpine <branch> |
one Alpine branch’s secdb, e.g. v3.22 (repeatable) |
--postgresql <major> |
one PostgreSQL major’s own security page, e.g. 13 (repeatable) |
--all-years |
every NVD year, not only this one, last one and missing ones |
--dry-run |
list what would be fetched, download nothing |
Each file is requested If-Modified-Since its copy on disk, downloaded
into .enodia-update/ beside it, loaded by the same code the CVE
lookup uses, and only then moved over the old copy — a truncated zip or
an HTML error page never replaces a working file. An unchanged file
costs one request (MariaDB, PostgreSQL and Atlassian send no
Last-Modified, so those are downloaded again and compared). Network
errors, 429 and 5xx are retried twice. One failure doesn’t stop the
rest; the exit status is 1 if any file failed. Run it from cron — the
next check or serve cycle picks the new files up.
TLS is verified against the system’s trusted roots, plus what a
cve.update block adds:
cve: update: ca_file: /etc/enodia/russian-trusted.pem # added to the system roots: PEM (one or many) or DER ca_dir: /etc/enodia/ca # every certificate file in it, likewise tls_skip_verify: false # true: verify nothing, for every downloadbdu.fstec.ru needs this: its chain ends at the Russian Trusted Root CA,
which almost no trust store carries, and the server doesn’t send its
intermediate (see БДУ ФСТЭК below). Without either, the
БДУ download fails with certificate signed by unknown authority and
the others still go through. The Root CA and the 2024 Sub CA are
published at http://nuc-cdp.digital.gov.ru/cdp/rootca_ssl_rsa2022.crt
and http://nuc-cdp.digital.gov.ru/cdp/subca_ssl_rsa2024.crt; a file
with both concatenated works as ca_file.
It names the files the same way the manual commands below do
(v3.22-main.json, 13.html, …), so the two can be mixed. The hosts it
contacts are listed on the Privacy page.
БДУ ФСТЭК
Section titled “БДУ ФСТЭК”One file, FSTEC’s full export (about 33 MB zipped):
curl -fL --cacert ru-chain.pem \ -o /var/lib/enodia/cve/bdu/vulxml.zip \ https://bdu.fstec.ru/files/documents/vulxml.zipbdu.fstec.ru uses a certificate from Russia’s national CA (Минцифры),
which isn’t in the usual system trust stores — a plain curl fails
with a certificate error. The server also doesn’t send its intermediate
certificate, and curl (unlike a browser) won’t fetch a missing one on
its own, so installing only the root isn’t enough. Build a bundle from
the root and the intermediate the site’s certificate names:
curl -fsS -o root.crt https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crtcurl -fsS -o sub.crt http://nuc-cdp.digital.gov.ru/cdp/subca_ssl_rsa2024.crt{ cat root.crt; echo; cat sub.crt; } > ru-chain.pemChecked live on 2026-09-23. If it stops working, the intermediate has
most likely been rotated: the site certificate’s own Authority
Information Access field names the current one (openssl s_client -connect bdu.fstec.ru:443 | openssl x509 -noout -ext authorityInfoAccess).
curl -k also gets the file, but skips verifying what you’re about to
feed into your security report.
NIST NVD
Section titled “NIST NVD”One file per year, nvdcve-2.0-<year>.json.gz, 2002 through the current
year. Put the ones you want in one directory:
mkdir -p /var/lib/enodia/cve/nvd && cd /var/lib/enodia/cve/nvdfor y in $(seq 2002 "$(date +%Y)"); do curl -fsSLO "https://nvd.nist.gov/feeds/json/cve/2.0/nvdcve-2.0-$y.json.gz"doneThe current year’s file is updated daily; older years change rarely.
Each file has a .meta sidecar (nvdcve-2.0-<year>.meta) with its size
and sha256 — note the hash is of the uncompressed JSON, not the
.gz.
Debian Security Tracker
Section titled “Debian Security Tracker”One file, the tracker’s full JSON export (about 80 MB), for debian
targets:
curl -fsSL -o /var/lib/enodia/cve/debian.json \ https://security-tracker.debian.org/tracker/data/json.json.gz and .json.zip copies work too.
Vendor OVAL
Section titled “Vendor OVAL”One file per distribution release in your fleet, all in one directory,
for ubuntu, linuxmint, rhel, rocky-linux, almalinux,
oracle-linux, astra-linux and redos targets:
| Targets | File |
|---|---|
| Ubuntu, Linux Mint (its Ubuntu base) | https://security-metadata.canonical.com/oval/com.ubuntu.<codename>.usn.oval.xml.bz2 |
| RHEL and Rocky Linux | https://security.access.redhat.com/data/oval/v2/RHEL<N>/rhel-<N>.oval.xml.bz2 |
| AlmaLinux | https://security.almalinux.org/oval/org.almalinux.alsa-<N>.xml.bz2 |
| Oracle Linux | https://linux.oracle.com/security/oval/com.oracle.elsa-ol<N>.xml.bz2 |
| Astra Linux SE 1.7, 1.8 | https://dl.astralinux.ru/astra/oval/<1.7|1.8>_x86-64/oval-definitions-alse-<1.7|1.8>.xml |
| RED OS 7.3, 8.0 | https://redos.red-soft.ru/support/secure/<7.3|8.0>/redos.xml |
mkdir -p /var/lib/enodia/cve/oval && cd /var/lib/enodia/cve/ovalcurl -fsSLO https://security-metadata.canonical.com/oval/com.ubuntu.noble.usn.oval.xml.bz2curl -fsSLO https://security.access.redhat.com/data/oval/v2/RHEL9/rhel-9.oval.xml.bz2curl -fsSL -o redos-8.0.xml https://redos.red-soft.ru/support/secure/8.0/redos.xmlFiles are taken as published, .xml or .xml.bz2. Which release a file
is for is read from its content, never from its name — so the two RED
OS files, both published as redos.xml, only need distinct names on
disk. Two files are refused on purpose, with an error naming the file
to use instead:
- Rocky Linux’s own OVAL (
org.rockylinux.rlsa-<N>.xml) — it holds a small fraction of Rocky’s advisories and doesn’t pass OVAL schema validation. Rocky rebuilds Red Hat’s packages with the same versions, so Rocky hosts are matched against Red Hat’s file. - Ubuntu’s
oci.variant — it checks the dpkg status file with regular expressions instead of packages.
All URLs checked live on 2026-10-02.
Alpine secdb
Section titled “Alpine secdb”Two files per Alpine branch in your fleet, main and community, for
alpine-linux targets. They share names across branches, so save them
under distinct ones:
mkdir -p /var/lib/enodia/cve/alpine && cd /var/lib/enodia/cve/alpinefor b in v3.20 v3.22; do for r in main community; do curl -fsSL -o "$b-$r.json" "https://secdb.alpinelinux.org/$b/$r.json" donedoneMariaDB’s own CVE table
Section titled “MariaDB’s own CVE table”One file, for mariadb targets: MariaDB’s own page “Security
Vulnerabilities (CVE) Fixed in MariaDB Community Server”, saved as is
in its Markdown source (about 320 KB):
curl -fsSL -o /var/lib/enodia/cve/mariadb.md \ https://mariadb.com/docs/server/security/cve/community-server.mdChecked live on 2026-10-09.
Atlassian’s vulnerability data
Section titled “Atlassian’s vulnerability data”One file, for jira, confluence, bitbucket and bamboo targets:
Atlassian’s vulnerability transparency export, the JSON this URL
returns, saved as is (about 2.3 MB, no login):
curl -fsSL -o /var/lib/enodia/cve/atlassian.json \ https://api.atlassian.com/vuln-transparency/v1/productsPostgreSQL’s security pages
Section titled “PostgreSQL’s security pages”For postgresql targets: the project’s security page saved as HTML. It
names only the majors supported today — for an older major, save its own
page (/support/security/<major>/) into the same directory:
mkdir -p /var/lib/enodia/cve/postgresql && cd /var/lib/enodia/cve/postgresqlcurl -fsSL -o security.html https://www.postgresql.org/support/security/curl -fsSL -o 13.html https://www.postgresql.org/support/security/13/nginx’s security advisories
Section titled “nginx’s security advisories”One file, for nginx targets: the advisories page saved as HTML:
curl -fsSL -o /var/lib/enodia/cve/nginx.html \ https://nginx.org/en/security_advisories.htmlAll three URLs checked live on 2026-10-09.
Configuration
Section titled “Configuration”A cve: block in enodia.yaml — not settings.yaml, since it changes
the evaluation, not just the display:
schemaVersion: 1cve: bdu: path: /var/lib/enodia/cve/bdu/vulxml.zip nvd: path: /var/lib/enodia/cve/nvd debian: path: /var/lib/enodia/cve/debian.json oval: path: /var/lib/enodia/cve/oval alpine: path: /var/lib/enodia/cve/alpine mariadb: path: /var/lib/enodia/cve/mariadb.md atlassian: path: /var/lib/enodia/cve/atlassian.json postgresql: path: /var/lib/enodia/cve/postgresql nginx: path: /var/lib/enodia/cve/nginx.htmltargets: - id: gitlab-main product: gitlab address: https://gitlab.example.com credentials: gitlab-token| Field | Accepts |
|---|---|
cve.bdu.path |
a .xml, .zip (the export as published), or .tar.gz/.tgz |
cve.nvd.path |
a single .json, .json.gz or .json.zip file, or a directory of them |
cve.debian.path |
the tracker’s export: .json, .json.gz or .json.zip |
cve.oval.path |
one OVAL file (.xml or .xml.bz2), or a directory of them |
cve.alpine.path |
one secdb .json file, or a directory of them |
cve.mariadb.path |
MariaDB’s community-server.md, saved as is |
cve.atlassian.path |
Atlassian’s vuln-transparency JSON, saved as is |
cve.postgresql.path |
PostgreSQL’s security page as HTML, or a directory of such pages |
cve.nginx.path |
nginx’s security_advisories.html, saved as is |
cve.update |
TLS options for enodia cve update only: ca_file, ca_dir, tls_skip_verify |
Relative paths resolve against the directory of the config file that
names them, the same as credentials_file. The block is read from
whichever config the run actually uses — --config, $ENODIA_CONFIG,
or the default search paths.
That includes check --from inventory.jsonl: an inventory collected
inside a closed network is correlated wherever check runs, as long as
a config with a cve: block is found there. With no config located at
all, check --from still works, just without CVEs.
A configured path that doesn’t exist is an error, not a silent
skip — check exits with stat ...: no such file or directory rather
than producing a report that quietly has no CVEs in it. Since 2.1,
enodia config validate checks that every configured path exists too,
so a typo shows up there first (since 2.2, cve.update.ca_file and
ca_dir too). Whether a file actually parses is still only found out
when a run loads it — or when enodia cve update downloads it.
First run and caching
Section titled “First run and caching”БДУ and NVD are stream-parsed and the result is cached in the OS cache
directory ($XDG_CACHE_HOME/enodia/cve, i.e. ~/.cache/enodia/cve by
default on Linux; ~/Library/Caches/enodia/cve on macOS;
%LocalAppData%\enodia\cve on Windows). The first run after a file changes parses it in full —
about a minute for all of NVD plus БДУ; measured on 2026-09-23 with
БДУ plus NVD’s 2026 file alone, 25 s. Every later run reads the cache:
0.2 s for the same data, an 11 MB cache. There is no TTL — the cache is
keyed on the files themselves (size and modification time) and on
enodia’s own product tables, so replacing a file, adding a year to the
NVD directory, or upgrading enodia each trigger a rebuild on their own.
Parsed OVAL is cached the same way — about 11 s to parse Ubuntu noble’s,
RHEL 9’s, AlmaLinux 9’s and Oracle Linux 9’s files together, most of it
bzip2. The Debian tracker export (about a second to parse) and Alpine’s
secdb (a few hundred KB) aren’t cached. With every source configured at
once (БДУ, NVD, Debian, eight OVAL files, Alpine), upstream measured
check at about 22 s cold and 3.4 s warm, peaking at 0.5–0.6 GB of
memory — less if cve.oval.path holds only the releases you actually
run.
enodia serve re-reads the cve: block and the files on every
--interval cycle (cheaply, from the cache), so replacing the files
from cron takes effect without restarting the server.
Where findings show up
Section titled “Where findings show up”check— aCVEScolumn in thecompactanddriftviews: the number of distinct CVEs affecting that exact version.-means no findings — none affect that version, there’s nocve:block, or enodia doesn’t match the product (see below); the column itself is always there.lifecycleandfleetdon’t carry the column.export --format html— the same column with an info link opening a per-target list: one line per CVE, most severe first, with links to NVD, cve.org and, for БДУ findings, the bdu.fstec.ru page; БДУ’s Russian text when БДУ has the CVE, NVD’s English description otherwise; and the rating as colored badges, e.g.CRITICAL · CVSS 3.1 9.8. Package-level findings are one line per package instead —linux 6.12.107-1 → 6.12.111-1, linked to the advisory that carries the fix, with its CVE list folded underneath. It’s pure CSS — the default offline report still contains no JavaScript at all.export --format json— every per-source finding in full under each assessment’scvesarray: the source (bdu,nvd, or a vendor’s:mariadb,atlassian,postgresql,nginx), advisory ID, CVE IDs, title, the source’s own severity text, the matched product name or CPE, the version range, and a parsed CVSS rating. Unlike the table and the HTML list, which count one line per CVE, JSON keeps every source’s finding separately — the same CVE can appear once from БДУ and once per matching NVD CPE. Package-level findings (sourcedebian,ovaloralpine) also carry the installed and fixed versions — see Reporting.export --format prometheus— no CVE data.
CVEs don’t affect severity or the exit code. SEVERITY is still
computed from the patch/lifecycle/branch axes only, and --fail-on
only knows those three axes too — a finding is a fact to look
at, not a verdict enodia has made on your behalf. Whether and how a CVE
should escalate severity is an open question upstream.
Which products are matched
Section titled “Which products are matched”91 of the 123 products: 81 by product name against БДУ and NVD (six of them also against their vendor’s own data — see below), each vendor/product name checked verbatim against the real full exports, and 10 Linux distributions per installed package (see the next section). See each product’s own page under Product setup for its sources.
Not matched, each for a reason:
- The other general-purpose Linux distributions (Fedora, CentOS Stream, Amazon Linux, openSUSE, …) — their CVEs are package vulnerabilities, a release number can’t say which packages have been patched since, and there’s no package-level source for them yet.
- The BSDs and Oracle Solaris — NVD records their patch levels
(FreeBSD’s
-p5, OpenBSD errata) in a CPE field this matcher doesn’t read; matching on the release alone would flag a fully patched host with every CVE ever fixed in that release. - ESXi and vCenter — the same problem: almost all their entries are
7.0+update_1-style literals. - TrueNAS — too few entries, versioned differently from what the probe reports.
- No usable data in either source — Kitsu, Zou, postgres_exporter, Perforce Proxy, Perforce Helix Swarm, Supermicro BMC, LibreTranslate, TorrServer, and Euro-Office (a fork with no entries of its own).
- PostHog — its NVD bounds are git commits, not versions.
generic— a hand-written parser has no product identity to look up.
Package-level CVEs for Linux distributions
Section titled “Package-level CVEs for Linux distributions”A release number can’t tell which packages on a host have been patched since, so these ten distributions are matched per installed package instead. Their probes read the installed packages and the running kernel in the same SSH round trip as the version itself, and each package is checked against its distribution’s own security data:
| Probe | Source | Key |
|---|---|---|
debian |
Debian Security Tracker | cve.debian.path |
ubuntu |
Canonical OVAL | cve.oval.path |
linuxmint |
Canonical OVAL, for its Ubuntu base | cve.oval.path |
rhel, rocky-linux |
Red Hat OVAL | cve.oval.path |
almalinux |
AlmaLinux OVAL | cve.oval.path |
oracle-linux |
Oracle OVAL | cve.oval.path |
astra-linux |
Astra Linux OVAL (SE 1.7, 1.8) | cve.oval.path |
redos |
RED OS OVAL (7.3, 8.0) | cve.oval.path |
alpine-linux |
Alpine secdb | cve.alpine.path |
Only CVEs that already have a fix newer than what’s installed are reported — what an upgrade (and, for the kernel, a reboot) would close. CVEs the vendor hasn’t fixed yet are left out: they’re the same on every host of a release and nobody can act on them, so they’d bury the actionable ones.
One finding per package, not per CVE. A lagging kernel alone can
carry over a thousand CVEs; a per-CVE list would be unreadable. Each
finding names the package, its installed version, the version that
closes every CVE in it, and the advisory carrying that fix (USN, RHSA,
ALSA, ELSA, Astra bulletin, ROS, or the Debian/Alpine tracker page).
The CVES column still counts CVEs, not packages.
Versions are compared by each package manager’s own rules — dpkg’s,
rpm’s and apk’s ordering, checked upstream against apt_pkg, rpm and
apk-tools on thousands of real version pairs each — plus AppStream
module streams (a package is only matched against its own stream’s
fixes), Oracle Linux’s architecture, FIPS and Ksplice variants, and the
running kernel rather than whatever kernel packages happen to be
installed. Every source was cross-checked upstream against
oscap oval eval, dnf updateinfo, python3-apt or apk version -t on
real hosts and containers, with identical results.
Proxmox VE gets package findings as a second target: an SSH
debian target on the same host,
next to its API proxmox one.
Debian’s linux package is only matched against a running Debian
kernel, so Proxmox’s own kernel isn’t mistaken for one.
Edition-aware matching
Section titled “Edition-aware matching”GitLab, HashiCorp Vault, Nextcloud and MongoDB publish separate CVE
lists for their community and enterprise editions. Their probes record
the server’s own edition in extra.enterprise, and a community instance
no longer sees enterprise-only findings — on real data, GitLab 19.2.2 CE
sees 4 of NVD’s 9, Nextcloud 27.1.3 CE 11 of 23. When the edition is
unknown (an older server that doesn’t report it), every finding is kept.
Since 2.2, a few more products’ versions say which line or edition a range applies to:
- Jenkins — weekly (
2.580) and LTS (2.568.3) releases get the same fix under different numbers, and both databases write a range for each. The version’s shape picks the line (two parts weekly, three LTS), so a fixed LTS is no longer flagged by the weekly bound of the same fix. - Splunk — only Splunk Enterprise ranges apply (splunkd’s own
product_typesays which); Splunk Cloud isn’t mapped. - pfSense — the probe reports Community Edition only, so pfSense Plus ranges never apply.
- WAPT — the server’s own edition (
communityorenterprise) is passed through as is. - Kafka — a Confluent Platform build (
7.6.1-ccs) gets no lookup: its own numbering would read as newer than every Apache Kafka bound.
Dell iDRAC and Synology DSM
Section titled “Dell iDRAC and Synology DSM”iDRAC: both databases name each iDRAC generation as its own product,
and their firmware numbers overlap (iDRAC7 and iDRAC8 both run 2.x, with
different fixes). The generation is read from the probe’s
extra.model, Redfish’s own model string: 11G is iDRAC6, 12G iDRAC7,
13G iDRAC8, 14G–16G iDRAC9, 17G iDRAC10. Without a model, only firmware
3.x and later is looked up — that can only be iDRAC9.
Synology DSM: a release is version, build and Update — Synology
writes DSM 7.2.1-69057 Update 6, NVD and БДУ 7.2.1-69057-6. Since
2.2 the probe also records the Update in extra.update, and both sides
are folded into one comparable version. An inventory collected before
2.2 has no extra.update and reads as Update 0: fixed Updates may be
flagged, none are missed.
The ssh probe covers any SSH
implementation, so it’s matched by banner: OpenSSH_… looks up
OpenSSH, dropbear_… looks up Dropbear, and any other SSH stack gets no
lookup rather than borrowing OpenSSH’s CVEs.
Vendors’ own data
Section titled “Vendors’ own data”БДУ and NVD often describe a fix in one branch as an open-ended range (“before 11.4.10”), which then covers every older branch too — including fixed releases and branches that never had the bug. Four vendors publish the per-branch truth themselves, and enodia reads it next to БДУ and NVD with one rule on top: where the vendor’s data knows a CVE, its verdict wins — a БДУ or NVD finding whose CVEs the vendor covers and doesn’t flag for this version is dropped. CVEs the vendor doesn’t list still come from БДУ and NVD.
| Key | Products | Source |
|---|---|---|
cve.mariadb.path |
mariadb |
MariaDB’s table of fixed CVEs |
cve.atlassian.path |
jira, confluence, bitbucket, bamboo |
Atlassian’s per-release vulnerability data |
cve.postgresql.path |
postgresql |
PostgreSQL’s security pages |
cve.nginx.path |
nginx |
nginx’s security advisories |
Without these keys the products are still matched against БДУ and NVD alone — with the overlap problem above.
MariaDB
Section titled “MariaDB”MariaDB maintains five or six release series at once. On real fleet versions, БДУ’s and NVD’s ranges flagged the latest, fully patched releases of maintained series (10.11.19, 11.4.13), while the same two databases missed 9 of the 21 CVEs MariaDB itself lists for 10.11.8.
cve.mariadb.path adds MariaDB’s own table of fixed CVEs, which names
the fixing release per series. CVEs the table doesn’t list (newer
than your downloaded copy, БДУ-only, or without a CVE id) still come
from БДУ and NVD.
How the table is read:
- A series with its own fix is vulnerable from its first release up to that fix.
- A series with no fix of its own that was still maintained when the CVE was fixed elsewhere is unaffected — MariaDB fixes every live series together.
- A series that had already ended by then is flagged for every release,
with the lowest fix in a newer series as the release to move to
(
FixStatussays so). This errs toward reporting on purpose, and only for ended series.
Atlassian
Section titled “Atlassian”Atlassian’s export lists every Jira Software, Jira Core, Confluence, Bitbucket and Bamboo release (Server and Data Center) with the CVEs it is affected by and the release that fixes each — third-party dependency CVEs included, which NVD’s Atlassian entries never list. The probe can’t tell Server from Data Center, so both lists are read. Jira Service Management numbers its releases on its own and isn’t mapped; release candidates and EAPs are skipped.
A target is judged within its own major.minor branch: from an affected release to the next one listed as fixing it, or to the branch’s end when no fix follows. Jira 10.3.26 isn’t flagged for a CVE Atlassian lists only for 10.1 and 11.3. Since Atlassian lists releases one by one, its verdict holds only for a release it lists — a release newer than your copy of the file keeps БДУ’s and NVD’s findings. Upstream measured the newest release of each maintained branch with no Atlassian findings, while older ones gain many: Jira 10.3.12 went from 4 CVEs to 119, almost all dependencies fixed in later 10.3 releases.
PostgreSQL
Section titled “PostgreSQL”The security page names, for every CVE, the supported majors it affects
and the fix in each. Its verdict covers only the majors the saved pages
name: the main page lists only majors supported today, so for an ended
major (13, 9.6) save its own page into the same directory — without it,
that major keeps БДУ’s and NVD’s findings. A major that had already
ended before a CVE came out is flagged with no fix when the CVE reaches
back to the oldest major still supported then, as with MariaDB’s ended
series. packaging rows (an installer or RPM build) are tracked but not
flagged. Upstream measured the current 18/17/16/15/14 releases going
from up to 55 БДУ findings each to none.
Each advisory lists the vulnerable versions and, per branch, the first
fixed release (1.31.3+, 1.30.4+): stable 1.30.5 is no longer flagged by
a range written up to the mainline fix. Branches that never got the fix
stay flagged; advisories for nginx/Windows only are skipped.
Known limitations
Section titled “Known limitations”- БДУ can over-report across branches. One БДУ entry often lists a separate range per maintenance branch, all sharing one lower bound, so a version that is already the fix on its own branch can still fall inside a sibling branch’s wider range (Confluence 8.3.3 against CVE-2023-22515 is the documented example; Synology DSM’s per-branch ranges do the same — DSM 7.2.1-69057 Update 8 gets 5 БДУ findings). NVD’s ranges for the same CVE carry their own lower bounds and don’t have this problem. enodia deliberately errs toward reporting a finding to double-check rather than silently missing a real one.
- NVD entries with no version constraint at all are dropped. Measured against the full exports, they were almost all decades-old CVEs attached to current releases; the cost is the rare genuinely-unfixed CVE recorded that way.
- Package-level coverage has gaps of its own. The Debian tracker only covers releases Debian’s security team still supports (bookworm, trixie, testing, sid) — older hosts get no package findings. Alpine edge has no numbered branch and gets none either. OVAL isn’t evaluated as a full interpreter: package signing keys aren’t checked, so a third-party package with a distribution package’s name is compared as if it were the distribution’s. Astra Linux’s kernel packages are compared as installed, not as running.
- NVD’s multi-product conditions (“vulnerable only with library Y”) aren’t evaluated — a probe reports one product per target, so each vulnerable entry for a matched product counts on its own.