product advisories update

This commit is contained in:
master
2025-12-30 16:05:16 +02:00
parent f2565a3224
commit e6ee092c7a
7 changed files with 2544 additions and 350 deletions

View File

@@ -0,0 +1,160 @@
## Product Advisory: Deterministic VEX-first vulnerability verdicts with CycloneDX 1.7
### 1) The problem you are solving
Modern scanners produce a long list of “components with known CVEs,” but that list is routinely misleading because it ignores *context*: whether the vulnerable code is shipped, configured, reachable, mitigated, or already fixed via backport. Teams then waste time on false positives, duplicate findings, and non-actionable noise.
A **VEX-first** approach solves this by attaching *exploitability/impact assertions* to SBOM components. In CycloneDX, this is expressed via the **Vulnerability / Analysis** model (often used as VEX), which can declare that a component is **not affected**, **under investigation/in triage**, **exploitable/affected**, or **resolved/fixed**, along with rationale/justification and other details. CycloneDX explicitly frames this as “vulnerability exploitability” context, including a `state` and a `justification` for why a vulnerability is (or isnt) a practical risk. ([cyclonedx.org][1])
The core product challenge is therefore:
* You will ingest **multiple statements** (vendors, distros, internal security, runtime evidence) that may **conflict**.
* Those statements may be **conditional** (only affected on certain OS, feature flags, build options).
* You must produce a **single stable, explainable verdict** per (product, vuln), and do so **deterministically** so audits and diffs are reproducible.
---
### 2) Product intent and outcomes
**Primary outcome:** Reduce noise while increasing trust: every suppression or escalation is backed by evidence and explainable logic.
**What “good” looks like:**
* Fewer alerts, but higher signal.
* Each vuln has a clear **final verdict** plus **reason chain** (“why this was marked not_affected/fixed/affected”).
* Deterministic replay: the same inputs produce the same outputs.
---
### 3) Recommended data contract (CycloneDX 1.7 aligned)
Use CycloneDX 1.7 as the canonical interchange for impact/exploitability assertions:
* **SBOM**: components + dependencies (CycloneDX and/or SPDX)
* **Vulnerability entries** with **analysis** fields:
* `analysis.state` (status in context) and `analysis.justification` (why), as described in CycloneDXs exploitability use case. ([cyclonedx.org][1])
* Optional ingress from **OpenVEX** or CSAF; normalize into CycloneDX analysis semantics (OpenVEX defines the commonly used status set `not_affected / affected / fixed / under_investigation`, and requires justification in `not_affected` cases). ([GitHub][2])
Graph relationships (if you use SPDX 3.0.1 as your internal graph layer):
* Model dependencies and containment via SPDX `Relationship` and `RelationshipType`, which formalize “Element A RELATIONSHIP Element B” semantics used to compute transitive impact. ([SPDX][3])
---
### 4) Product behavior guidelines
#### A. Single “Risk Verdict” per vuln, backed by evidence
Expose one final verdict per vulnerability at the product level, with an expandable “proof” pane:
* Inputs considered (SBOM nodes, relationship paths, VEX statements, conditions).
* Merge logic explanation (how conflicts were resolved).
* Timestamped lineage: which feed/source asserted what.
#### B. Quiet-by-design UX
* Default views show only items needing action: **Affected/Exploitable**, and **Under Investigation** with age/timeouts.
* “Not affected” and “Fixed/Resolved” are accessible but not front-and-center; they primarily serve audit and trust.
#### C. Diff-aware notifications
Notify only on **meaningful transitions** (e.g., Unknown→Affected, Affected→Fixed), not on every feed refresh.
---
### 5) Development guidelines (deterministic resolver)
#### A. Normalize identifiers first
Create a strict canonical key for matching “the same component” across SBOMs and VEX:
1. prefer **purl**, then **CPE**, then (name, version, supplier).
2. persist alias mappings (vendor naming variance is normal).
#### B. Represent the world as two layers
1. **Graph layer** (what is shipped/depends-on/contains what)
2. **Assertion layer** (CycloneDX 1.7 vulnerability analysis statements, plus optional runtime/reachability evidence)
Do not mix them—keep assertions as immutable facts that the resolver evaluates.
#### C. Condition evaluation must be total and deterministic
For each assertion, evaluate conditions against a frozen `Context`:
* platform (OS/distro/arch), build flags, enabled features, packaging mode
* runtime signals (if used) must be versioned and hashed like any other input
If a condition cannot be evaluated, treat it explicitly as **Unknown**, not false.
#### D. Merge conflicts via a documented lattice
Define a monotonic merge function that is:
* **commutative** (order independent),
* **idempotent** (reapplying doesnt change),
* **associative** (supports streaming/parallel merges).
A pragmatic priority (adjust to your policy):
1. **Fixed/Resolved** (with evidence of fix scope)
2. **Not affected** (with valid justification and conditions satisfied)
3. **Affected/Exploitable**
4. **Under investigation / In triage**
5. **Unknown**
CycloneDXs exploitability model explicitly supports “state + justification” to make “not affected” meaningful, not a hand-wave. ([cyclonedx.org][1])
#### E. Propagation rules must be explicit
Decide and document how assertions propagate across the dependency graph:
* When a dependency is **Affected**, does the product become Affected automatically? (Typically yes if the dependency is shipped and used, unless a product-level assertion says otherwise.)
* When a dependency is **Not affected** due to “code removed before shipping,” does the product inherit Not affected? (Often yes, but only if you can prove the affected code path is absent for the shipped artifact.)
* Keep propagation rules versioned to avoid “policy drift” breaking deterministic replay.
#### F. Always emit a proof object
For every final verdict emit:
* contributing assertions (source IDs), condition evaluations, merge steps
* the graph path(s) that made it relevant (SPDX Relationship chain or CycloneDX dependency references)
This proof is what lets you be quiet-by-design without losing auditability.
---
### 6) Interop guidance (OpenVEX / CSAF → CycloneDX 1.7)
If you ingest OpenVEX:
* Map OpenVEX status to CycloneDX analysis state (policy-defined mapping).
* Enforce OpenVEX minimums: `not_affected` should have a justification/impact statement. ([GitHub][2])
If you ingest CSAF advisories:
* Treat them as another assertion source; do not let them overwrite higher-confidence internal evidence without explicit precedence rules.
---
### 7) Testing and rollout checklist
* **Golden test vectors**: fixed input bundles (SBOM + assertions + context) with expected verdicts.
* **Determinism tests**: shuffle assertion ordering; results must be identical.
* **Regression diffs**: store prior proofs; verify only intended transitions occur after feed updates.
* **Adversarial cases**: conflicting assertions, partial conditions, alias mismatches, missing dependency edges.
---
### 8) Common failure modes to avoid
* Treating “not affected” as a suppression without requiring justification.
* Allowing “latest feed wins” behavior (non-deterministic and unauditable).
* Mixing runtime telemetry directly into SBOM identity (breaks replay).
* Implicit propagation rules (different engineers will interpret differently; results drift).
If you want, I can also provide a short, implementation-ready “resolver contract” (types, verdict lattice, proof schema) that is CycloneDX 1.7-centric while remaining neutral to whether you store the graph as CycloneDX dependencies or SPDX 3.0.1 relationships.
[1]: https://cyclonedx.org/use-cases/vulnerability-exploitability/?utm_source=chatgpt.com "Security Use Case: Vulnerability Exploitability"
[2]: https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md?utm_source=chatgpt.com "spec/OPENVEX-SPEC.md at main"
[3]: https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Classes/Relationship/?utm_source=chatgpt.com "Relationship - SPDX Specification 3.0.1"