Check an SBOM against the CVE-linked package mapping and NVD's CPE configurations (verdictless)

POST an SBOM. The join runs on this server; nothing from the body is stored or forwarded to a third party. Accepted bodies: {"purls": ["pkg:npm/lodash", …]}, CycloneDX JSON 1.2 through 1.7 (metadata.component and every nested components[] array) and SPDX JSON (packages[].externalRefs referenceType "purl"). A purl goes to the open-source package join on OSV.dev data; version suffixes in purls are read and set aside. A cpe on a device, firmware or operating-system component (component.cpe, else the evidence.identity entry with field cpe and the highest confidence; a CPE 2.3 formatted string or a CPE 2.2 URI such as Nmap prints) goes to the CPE join on NVD's configurations, and cpe=all sends every component's cpe. A body whose purls sit in a plain list, SPDX or top-level components[] gets the first version's answer, with three corrections: a blank purl is skipped, summary.unresolved_purls counts every unresolved purl while the list stops at 200, and the 1 MB body cap counts 1,048,576 bytes of UTF-8 where the first version counted characters. Purls in metadata.component and in nested components join too and count in the summary, and so does a purl on a component past the walk's caps. A CycloneDX specVersion string outside 1.2 through 1.7 answers 400; a specVersion that is not a string reads as unknown. When a component goes to the CPE join, or the call passes components=1, the answer adds input, component_summary, components (one result per walked component: matched, runs_on_only, no_match_in_our_data, counts_only, over_cap or unresolved, with a reason), cpe_summary, cpe_matched, which lists each CVE with its attachments to the BOM's components, and cpe_configurations, which carries NVD's configurations whole: a range attaches to a component when a vulnerable entry names its vendor and product and the configuration's other parts sit in the same device. Ranges and bounds go out verbatim, and the server orders no versions; it compares a version only as a string, for a partner part and for a version NVD names beside an update. An NVD end bound marks where NVD's range stops, OSV's fixed versions are upgrade targets, and affected_through is the last affected version. A package or component with no match holds no CVE in our data; the source may still hold one. format=cyclonedx, or an Accept header that ranks application/vnd.cyclonedx+json first, asks for a CycloneDX 1.6 document (1.7 with spec_version=1.7): a tie with an explicit application/json entry answers JSON, and a tie with a wildcard answers CycloneDX; an Accept entry that names a CycloneDX version other than 1.6 or 1.7 is set aside, so the header's next choice decides. That answer is built and stays off until the cve-security property namespace is registered in the CycloneDX property taxonomy; https://cve-security.com/cyclonedx-properties lists its properties. While it is off, format=cyclonedx and an Accept header that excludes JSON answer 501, and a header that also accepts JSON (application/json, or a wildcard with no application/json;q=0) gets the JSON answer. XML and protobuf BOMs answer 415 with the cyclonedx-cli conversion. Caps: 1 MB (1,048,576 bytes of UTF-8) body, 2,000 resolvable purl keys, 20,000 components to depth 32 and 4 million characters of paths and refs, 200 CPE keys, 25 CVEs a CPE key, 2,000 CVEs from the CPE join, per-call budgets for D1 rows read, matches held, attachment units and the attachment rule's steps, and byte budgets on the components (4 MB) and attachments (6 MB) the JSON answer lists; a component past one reads over_cap with its reason or is counted as not walked, what a listing budget holds back is counted, and component_summary.complete reads false. Counts as one request, also when the analysis stops on an unexpected error or on a datastore error after some of its reads ran.

post/api/sbom

Request

  • Base URL: https://cve-security.com
  • URL: https://cve-security.com/api/sbom
  • Auth: one of:
    • HTTP bearer
    • API key in header X-API-Key

Query parameters

format'json' | 'cyclonedx'

json (the default) or cyclonedx. The CycloneDX answer answers 501 until the cve-security property namespace is registered; see /cyclonedx-properties.

spec_version'1.6' | '1.7'

The CycloneDX version of a format=cyclonedx answer. The Accept header's version parameter works too, and an Accept entry that names another version is set aside.

cpe'all'

all sends every component's cpe to the CPE join. By default only device, firmware and operating-system components go, because SBOM tools put guessed CPEs on every OS package.

components'1'

1 adds the per-component results to a JSON answer whose BOM sends no component to the CPE join.

Response

The JSON answer (the default), or a CycloneDX document for format=cyclonedx once that answer is on.

object required

summary{purls_received, packages_checked, packages_with_cves, packages_without_match, unresolved_purls, total_cves, kev_cves, truncated_at?}, matched[]{pkg_key, ecosystem, name, input_purls, cve_count, cves[]{cve_id, url, severity, epss, cisa_kev, known_ransomware_use, advisory, advisory_url, ranges[]{type, events, fixed?|affected_through?}}}, packages_without_match[], unresolved_purls[]. With a CPE component or components=1, also: input{format, spec_version, serial_number, version, cpe_routing, input_issues?, spdx?{packages, packages_without_purl{count, listed[]{path, name?, spdx_id?, cpe?}, truncated_at?}, cpe_refs_not_read{count, listed[], truncated_at?}}}, component_summary{walked, listed, matched, runs_on_only, no_match_in_our_data, counts_only, over_cap, unresolved, not_walked_component_cap, not_walked_depth_cap, not_walked_path_budget, purls_not_read (purl values the walk could not read: a number, an object or a string past 1,024 characters, in a plain purls list or on a component; a blank purl is skipped), spdx_packages_without_purl?, spdx_cpe_refs_not_read?, services, listing_caps?{components, bytes}, complete (true only when the call checked everything the body sent in full and the answer lists it: no component capped, too broad to list or unresolved, none past the walk's caps, no routed cpe left unread even where the component's purl ran, purls_not_read 0, no purl unresolved or past the key cap, no SPDX package without a purl reference and no SPDX CPE reference left unread, every CPE key listed with all its CVEs, even behind a purl match, every CVE loaded whole, every walked component listed in components[] and every attachment listed)}, components[] (the first 5,000, up to 4 MB, in walk order){path, bom_ref (a generated one reads cvesec-gen/ and the component's walk index), bom_ref_generated?, bom_ref_input? (the caller's bom-ref when the BOM repeated it or it starts with urn:cdx:, the BOM-Link prefix), type, group, name, version, is_external?, version_range?, purl, cpe, cpe_via, cpe_confidence, assembly (the path of the component's nearest device, or bom when metadata.component is the device and the component sits outside every other device), result, reason?, purl_key, purl_result, purl_reason?, cpe_formatted_string, cpe_key, cpe_result, cpe_reason?, cve_count, cve_count_over?, cves_returned, cves_not_loaded?, input_issues?}, cpe_summary{components_routed, cpe_keys, cpe_keys_listed, components_matched, components_runs_on_only, components_without_match, components_counts_only, components_over_cap, components_unresolved, total_cves, kev_cves, cves_not_loaded, attachments, attachments_attached, attachments_not_listed, attachment_units, attachment_steps, components_attach_budget, rows_read, rows_held, caps{cpe_keys, cves_per_key, broad_key_cves, rows_read, census_rows, rows_held, cves, attachment_units, attachment_steps, attachment_bytes}}, cpe_matched[]{cpe_key, vendor, product, role, components[], cve_count, cves_returned, cves_not_loaded?, cves[]{cve_id, url, severity, epss, cisa_kev, known_ransomware_use, attachments[]{bom_ref, configuration, role, pairing, attached, partner?{bom_ref, node, match}, entries[]{node, match, attaches, pairing?, qualifiers?[]{attribute, nvd, caller, state}}, entries_other_revisions?, vulnerable_entries?[]{node, match, bom_ref?}}, attachments_not_listed?}}, cpe_configurations{<CVE id>: {configurations_match_count, configurations_may_be_incomplete, configurations[]{n, names_bom_key, operator, negate, nodes[]{operator, negate, matches[]{criteria, vulnerable, version_start_including?, version_start_excluding?, version_end_including?, version_end_excluding?}}}}}. An attachment's entries point at nodes[node].matches[match] of the configuration it names in cpe_configurations; pairing reads single, paired, partner_absent, partner_version_differs, partner_version_unknown, negated or external_component. An entry that names an update beside a version attaches only when the component's CPE carries both, and its qualifiers show the version. The attachments are listed up to 6 MB in the answer's order; attachments_not_listed counts the rest per CVE. _meta{attribution, absence_semantics, privacy}, plus cpe_attribution, cpe_semantics, cpe_absence_semantics and cpe_routing with the CPE keys.

Changes

No recorded changes to this operation across all 1 revision of this API.