save progress

This commit is contained in:
master
2026-01-09 18:27:36 +02:00
parent e608752924
commit a21d3dbc1f
361 changed files with 63068 additions and 1192 deletions

View File

@@ -0,0 +1,161 @@
Heres a simple way to make vulnerability triage almost noisefree: combine **static SBOM callgraph pruning** with **runtime reachability hints** before making a VEX decision.
---
# Why this matters (plain English)
* Static scanners flag lots of CVEs that your app never calls.
* Runtimes (traces, signals) know what actually executed.
* Merging the two yields “only the CVEs that matter,” so your VEX is credible and quiet.
---
# The hybrid model (static → dynamic → VEX)
1. **Static stage (Sbomer + Feedser assist)**
* Build SBOM (CycloneDX/SPDX).
* Generate a **perpackage call graph** (library → functions → entrypoints).
* Compute a **pruned reachable set** using import graphs, symbol tables, and package metadata.
* Output: `reachability_static.json` (component → callable IDs).
2. **Dynamic stage (Signals + Scheduler traces)**
* Ingest **runtime traces** (e.g., eBPF/ETW/CLR Profiler/JFR) from Schedulermanaged jobs.
* Normalize to **reachability vectors**: `(component, symbol, freq, last_seen, context)`.
* Output: `reachability_runtime.json`.
3. **Decision stage (Vexer)**
* For each CVE → vulnerable symbols (from advisories/OSVs, deltasigs if available).
* If vulnerable symbol ∉ static set → **Not Affected (NA: not reachable)**.
* If ∈ static but ∉ runtime → **Under Investigation / Likely NA** (confidence < 1).
* If runtime **Affected** with confidence and evidence URIs.
* Emit **VEX** entries with justification (`not_provided_code_path`, `requires_config`, `fixed`, etc.) and confidence scores.
---
# Minimal PoC plan (2 weeks of evening work)
**Goal:** Let **Vexer** import runtime reachability vectors from **Scheduler** traces and use them to gate VEX verdicts.
### 0) Contracts (day 1)
* **Schema:**
* `reachability_static.jsonl`: `{ component, version, symbols:[...] }`
* `reachability_runtime.jsonl`: `{ component, symbol, last_seen, count, context:{pid, container, route}}`
* **Evidence URIs:** `stella://signals/<trace-id>#symbol=<name>`
### 1) Static extractor (days 24)
* Sbomer plugin: emit **symbol list + call graph** per artifact.
* Start with **.NET**: use Roslyn/IL metadata to map `assembly → type → method`.
* Heuristic fallbacks for native: ELF/PE export tables.
### 2) Runtime collector (days 36)
* Signals module:
* .NET CLR Profiler or EventPipemethod enter/leave (sampling ok).
* Map back to `(assembly, type, method)` + container tags.
* Scheduler: batch traces into **reachability vectors** and push to **Router**.
### 3) Vexer importer (days 68)
* New `Vexer.Reachability` package:
* Merge static + runtime with **component coordinate normalization** (purl).
* `bool IsRuntimeReachable(component, symbol)`; `ReachabilityScore 0..1`.
### 4) VEX decision filter (days 810)
* For each CVE advisory record (from Feedser): vulnerable symbols lookup.
* Decision table:
* `Runtime=1` **Affected (A)**.
* `Static=1, Runtime=0` **NA (Not reachable) with low confidence** unless policy overrides.
* `Static=0` **NA (No code path)**.
* Emit CycloneDX VEX or CSAF with **justifications + evidence links**.
### 5) UI & Ops (days 1014)
* **Stella UI:** badge per CVE: `Affected / NA / Probable NA`, hover shows symbols and lastseen.
* **Policy Engine:** org rules like treat Probable NA as NA after 14 days of runtime with p95 traffic.”
* **Notify:** only alert on `Affected` or `Probable NA → A` transitions.
---
# Data model & code stubs (illustrative)
**Vexer reachability interface**
```csharp
public record SymbolRef(string Purl, string Assembly, string Type, string Method);
public interface IReachabilityIndex {
bool InStatic(SymbolRef s);
bool InRuntime(SymbolRef s, TimeSpan since, out int count);
double Score(SymbolRef s); // 0..1 weighted by freq/recency
}
```
**Decision kernel**
```csharp
VexVerdict Decide(Cve cve, IEnumerable<SymbolRef> vulnSyms, IReachabilityIndex idx) {
var anyRuntime = vulnSyms.Any(s => idx.InRuntime(s, TimeSpan.FromDays(14), out _));
var anyStatic = vulnSyms.Any(s => idx.InStatic(s));
return anyRuntime ? VexVerdict.Affected
: anyStatic ? VexVerdict.ProbableNotAffected // gated by policy window
: VexVerdict.NotAffected;
}
```
**Evidence snippet in VEX (CycloneDX)**
```json
{
"vulnerability": { "id": "CVE-2025-12345" },
"analysis": {
"state": "not_affected",
"justification": "Vulnerable_code_not_in_execute_path",
"response": [ "will_not_fix" ],
"detail": "Symbols present but not executed across 14d p95 traffic",
"evidence": [
"stella://signals/trace-9f12#symbol=Contoso.Crypto.Rsa::Sign"
]
}
}
```
---
# Where it plugs into StellaOps
* **Sbomer**: adds callgraph/symbol export plugin.
* **Signals**: runtime tracer + compressor reachability vectors.
* **Scheduler**: tags traces by job/tenant/env; hands them to Router.
* **Vexer**: new Reachability importer + decision filter.
* **Feedser**: enriches CVEs with symbol hints (from OSV, deltasigs).
* **Policy Engine**: organization rules for confidence windows.
* **Notify/UI/Timeline**: surface verdicts, evidence, and flips over time.
---
# Guardrails & edge cases
* **Backports:** pair with your existing *binarydelta signatures* so fixed but looks vulnerable becomes **NA (fixed by backport)** even if symbol name matches.
* **Lazy paths & feature flags:** allow **context filters** (route, tenant, env) before declaring NA.
* **Airgapped:** ship traces via offline bundle (`*.signals.zip`) and replay.
---
# Next steps I can do now
1. Draft the JSON schemas + purl mapping table.
2. Add the `Vexer.Reachability` package and wire the decision filter.
3. Provide a tiny sample repo (toy service + vulnerable lib) to demo **A → Probable NA → NA** as traffic evolves.
If you want, Ill generate the initial schemas and a .NET tracer checklist so you can drop them into `docs/modules/`.