Sign in

CVEs & SBOM

The fourth security surface answers a different question from the other three. Findings asks what is wrong with the code; indicators asks what the binary does; malware asks whether it is malicious. This surface asks whether the binary contains a known-vulnerable version of a known component.

3 detection layers · 21 rule entries · 22 distinct CVE IDs · one pinned wire schema (openbinary.package-sbom-v1).

The mechanism is version comparison, not code-shape analysis. The engine unpacks a firmware blob or container, identifies the components inside, extracts each component's version string, and compares against curated rules that map (component, max_vulnerable_version) pairs to MITRE CVE IDs. The output is a software bill of materials with CVE attribution per component.

This is the right tool for firmware audits, supply-chain reviews, and any context where the binary in question is a wrapper around a tree of upstream packages. It is the wrong tool for the binary itself — does your code contain a vulnerability? is what Findings answers.

CVE detail attached to each component is upstream fields only: name, severity, description. No patch guidance, no "upgrade to version X" recommendation, no remediation advice. The no-remediation policy is intentional and applies across the entire engine.

Coverage at a glance

LayerRulesCVEsWhat it catches
L1 path patterns63Vendor binaries without version banners (Zyxel, generic Apache / Samba / CUPS); 3 rules are presence-only without CVE attribution
L2 version banners717BusyBox, OpenSSL, Dropbear (×2), dnsmasq, Linux kernel (presence-only), OpenSSH
L3 firmware version84Zyxel NAS326 (AAZF.4/5/6), VMG8825, ZyWALL / USG (V4.6/70/71/72) — vendor version ranges share CVEs
Total2122 unique (CVE-2020-9054 and CVE-2023-28771 each appear in both L1 and L3)

Coverage is intentionally narrow and high-precision. The curation rule for a new entry: it has to be either (a) an upstream open-source package with a stable version banner and a tracked CVE list, or (b) a vendor firmware variant with a published advisory that names the version range. New entries land via PR with the advisory reference in the commit message; nothing is auto-imported from NVD.

The three-layer stack

Three independent layers run in sequence and aggregate into one SBOM document. Each layer trades a different mix of precision and recall.

L1 — Path patterns

Substring-matching against the extracted filesystem tree. Six entries flagging vendor-specific binaries that don't carry a version banner — /zysh (Zyxel shell, CVE-2022-30525), weblogin.cgi (CVE-2020-9054), and generic component paths like samba, apache-httpd, cups, and /pluto (IPsec). The weakest layer by design: confirms presence but not version. False-positive rate is high for vendor-specific entries that already shipped a patched build, but the false-negative rate is low — anything that ships the named binary at all gets flagged for review.

L2 — Per-binary version banners

The strongest layer for upstream open-source packages. Seven rules across six upstream components — BusyBox, OpenSSL, Dropbear (two rules), dnsmasq, Linux kernel, OpenSSH. Each rule names a regex prefix ("BusyBox v", "OpenSSL ", "dropbear_") and a maximum vulnerable version. The pipeline walks each extracted binary's NUL-terminated printable runs, matches the prefix, parses the version, and does a semver-style comparison.

Example matches:

When an upstream package ships a version banner, the match is precise and the version-floor check is exact. The trade-off: custom builds that strip the banner (or vendors that fork without preserving it) are misses. The version comparator is conservative on parse failure — if the string doesn't parse, the rule does not fire.

L3 — Firmware-version lookup

The strongest layer for vendor-specific CVEs that map directly to a firmware version. Eight rules covering vendor firmware version strings — Zyxel NAS326 V5.21(AAZF.4) and adjacent AAZF variants, VMG8825 7.3.245.300, ZyWALL and USG V4.x releases. The pipeline reads the container header's version string and substring-matches against the rule table.

Example matches:

The firmware-level signal is decisive — a router shipping NAS326 V5.21(AAZF.4) has CVE-2020-9054 regardless of which individual binary the analyst is looking at. Requires manual curation per vendor; the rule table grows as new vendor advisories land.

The SBOM schema

Every consumer reads the same wire shape: openbinary.package-sbom-v1.

Per-component row.

FieldMeaning
nameComponent name (busybox, openssl, nas326-firmware)
versionExtracted version string, or null for L1 (path-pattern, no version)
categorycrypto, network, core, vendor, os, etc. — coarse bucket for grouping in the UI
supplierUpstream project or vendor (OpenSSL Project, Zyxel, BusyBox)
evidenceWhich layer matched: binary_version, path_pattern, or firmware_version
binariesCount of extracted files referencing this component (multiple ELFs linking the same OpenSSL count once at the component level)
example_pathsUp to three sample paths into the extracted tree
cvesArray of CVE IDs matched to this (component, version) pair

Top-level aggregation.

FieldMeaning
firmware_versionContainer-header version string, nullable
firmware_cvesCVE IDs matched at the firmware-version layer (L3)
componentsSorted: CVE count desc, then binary count desc, then name asc
statsfiles_extracted, components_total, components_versioned, components_with_cves, components_vendor, unique_cve_ids

Worked example — NAS326 firmware V5.21(AAZF.4).

firmware_version: "V5.21(AAZF.4)"
firmware_cves:    ["CVE-2020-9054"]
top component:    openssl 1.0.2h
                  4 CVEs across 17 binaries
                  CVE-2019-1559, CVE-2021-3711, CVE-2021-3712, CVE-2022-0778
stats:            6513 files extracted, 10 components total,
                  5 versioned, 7 with CVEs, 3 vendor,
                  11 unique CVE IDs

How it integrates

The producer unpacks a firmware image into a temp dir, runs all three CVE scanners over the extracted tree, aggregates per (name, version) key, serializes to JSON, and drops the temp dir before return. No on-disk extracted tree survives the call. Per-file read errors are tolerated (capped at 4 MiB per file); a single unreadable file does not abort the SBOM build.

The consumer side in openbinary accepts the produced JSON at POST /api/v1/package/{sha256}/sbom, validates the schema header, and persists to its package store. The frontend renders the row table with no shape transformation — the schema is the contract.

openbinary.package-sbom-v1 is the pinned name. Field additions within v1 are non-breaking (the frontend drops unknown fields); field-semantics changes bump to v2.

What this surface does not do

Where this fits

CVE/SBOM is the parallel-but-orthogonal fourth surface. The other three security surfaces (Findings, Indicators, Malware) run on the binary's own code; this one runs on the inventory of upstream components the binary bundles. A firmware audit needs all four — bundled OpenSSL with a known CVE is a different problem from the firmware's own custom HTTP daemon having a stack-overflow CWE, and both are different from the firmware shipping a backdoor that scores Malicious on the verdict surface.

See Findings for the code-shape CWE catalog, Indicators for capability tagging, Malware for the verdict composer, and Architectures for the unpack-format coverage matrix.