Files
git.stella-ops.org/docs/product-advisories/05-Dec-2025 - Design Notes on Smart‑Diff and Call‑Stack Analysis.md
master a3c7fe5e88
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
add advisories
2025-12-09 18:45:57 +02:00

12 KiB
Raw Blame History

Heres a compact blueprint for two highimpact StellaOps features that cut noise and speed triage: a smartdiff scanner and a callstack analyzer.

Smartdiff scanner (rescore only what changed)

Goal: When an image/app updates, recompute risk only for deltas—packages, SBOM layers, and changed functions—then attach machineverifiable evidence.

Why it helps (plain English):

  • Most “new” alerts are repeats. Diffing old vs new narrows work to just what changed.
  • If a vulnerable API disappears, autodraft a VEX “not affected” (NA) with proof.
  • Evidence (DSSE attestations + links) makes audits fast and deterministic.

Inputs to diff:

  • Package lock/manifest (e.g., package-lock.json, Pipfile.lock, go.sum, pom.xml, packages.lock.json).
  • Image layer SBOMs (CycloneDX/SPDX per layer).
  • Functionlevel CFG summaries (per language; see below).

Core flow (pseudocode):

prev = load_snapshot(t-1)   // lockfiles + layer SBOM + CFG index + reachability cache
curr = load_snapshot(t)

Δ.pkg   = diff_packages(prev.lock, curr.lock)        // added/removed/changed packages
Δ.layers= diff_layers(prev.sbom, curr.sbom)          // image files, licenses, hashes
Δ.funcs = diff_cfg(prev.cfgIndex, curr.cfgIndex)     // added/removed/changed functions

scope = union(
  impact_of(Δ.pkg.changed),
  impact_of_files(Δ.layers.changed),
  reachability_of(Δ.funcs.changed)
)

for f in scope.functions:
   rescore(f)  // recompute reachability, version bounds, EPSS, KEV, exploit hints

for v in impacted_vulns(scope):
   annotate(v, patch_delta(Δ)) // symbols added/removed/changed
   link_evidence(v, dsse_attestation(), proof_links())

for v in previously_flagged where vulnerable_apis_now_absent(v, curr):
   emit_vex_candidate(v, status="not_affected", rationale="API not present", evidence=proof_links())

Evidence & provenance:

  • Emit DSSE envelopes for: (a) diff result, (b) rescoring inputs, (c) VEX candidates.
  • Attach proof links: Rekor entry, content digests, source commit, layer digest, and normalized lockfile hash.
  • Deterministic IDs: sha256(canonical-json(record)).

Data model (minimal):

  • Delta.Packages { added[], removed[], changed[{name, fromVer, toVer}] }
  • Delta.Layers { changed[{path, fromHash, toHash, licenseDelta}] }
  • Delta.Functions { added[], removed[], changed[{symbol, file, signatureHashFrom, signatureHashTo}] }
  • PatchDelta { addedSymbols[], removedSymbols[], changedSignatures[] }

.NET 10 implementation hints:

  • Projects: StellaOps.Scanner.Diff, StellaOps.Scanner.Rescore, StellaOps.Evidence.
  • Use System.Formats.Asn1/System.Security.Cryptography for digests & signing adapters.
  • Keep a contentaddressed cache by (artifactDigest, toolVersion) to make rescoring O(Δ).

Language normalizers (lockfiles → canonical):

  • Node: parse package-lock.json v2/v3 → {name, version, resolved, integrity}.
  • Python: consolidate pip freeze + pipdeptree or poetry.lock into name/version/source.
  • Java: mvn -DskipTests -q help:effective-pom + dependency:tree -DoutputType=json.
  • Go: parse go.sum + go list -m -json all.
  • .NET: dotnet list package --format json + packages.lock.json.

Callstack analyzer (fast reachability + readable explainers)

Goal: Rank vulns by whether your code can realistically hit the vulnerable sink, and show a minimal, humanreadable path (“why here?”).

Strategy: hybrid analysis

  • Static precompute: Build languagespecific call graphs (normalize package symbols, collapse known framework boilerplate). Techniques: CHA (Class Hierarchy Analysis), RTA (Rapid Type Analysis), and Sparkstyle dataflow over edges.
  • JIT refinement: On demand, prune with types/pointsto from build artifacts (PDBs, dotnet build metadata, javac -h, tsc --declaration), eliminate dead generics, inline trivial wrappers.
  • Path collapse: Merge equivalent prefixes/suffixes; cap frames to the smallest usercode slice plus critical sink frames.

Scoring & ranking:

  • score = user_code_distance^-1 * sink_criticality * evidence_weight
  • user_code_distance: hops from repo code to sink (shorter = riskier).
  • sink_criticality: CWE/AV:N + KEV/EPSS boost.
  • evidence_weight: runtime hints (observed stack traces, symbols present).

Explainer format (what triage sees):

[Reachable: HIGH] CVE-2024-XXXX in log4j-core@2.14.0
why here?  MyService.Process() → LoggingUtil.Wrap() → org.apache...JndiLookup.lookup()
minimal path (3/17 frames), pruned 14 library frames
proof: layer sha256:…, PDB match, symbol hash match, DSSE att#… (click to expand)

.NET 10 building blocks:

  • Build symbol index from PDBs (Microsoft.DiaSymReader), Roslyn analyzers for method refs.
  • Generate a compact call graph (StellaOps.Reach.Graph) with node IDs = sha256(normalized-signature).
  • JIT refinement: read IL (System.Reflection.Metadata) to resolve virtual dispatch edges when type sets are small (from compile artifacts).
  • Renderer: keep to ≤5 frames by default; toggle “show hidden frames”.

CFG + function diff for rescoring (bridge to smartdiff):

  • Store perfunction signature hash and basicblock count.
  • On change, register function for rescoring reachability + sinks affecting that symbol.

Minimal deliverables to get moving (1 sprint)

  1. Delta core: canonical lockfile/Layer/Symbol diff + patchdelta annotator.
  2. Rescore loop: take Delta → select functions → recompute reachability & risk.
  3. Explainer renderer: minimalframes call path with “why here?” badges.
  4. Evidence emitter: DSSE envelopes + proof links; VEX NA when vulnerable APIs vanish.
  5. Cache & determinism: contentaddressed store; stable JSON; golden tests.

If you want, I can generate the .NET 10 project skeletons (StellaOps.Scanner.Diff, StellaOps.Reach.Graph, StellaOps.Evidence) and stub methods next. Stella Ops big advantage is that it treats security findings as versioned, provable changes in your system (not a perpetual firehose of “still vulnerable” alerts). That unlocks a bunch of practical wins:

1) Massive noise reduction via “delta-first” security

Most scanners re-report the whole universe on every build. Stella Ops flips it: only rescore what changed (packages, image layers, symbols/functions), and inherit prior conclusions for everything else.

What you get:

  • Fewer duplicate tickets (“same CVE, same component, nothing changed”)
  • Less rescanning cost and faster CI feedback
  • A clear answer to “whats new and why?”

Why this is a real moat: making incremental results reliable requires stable canonicalization, caching, and evidence that the diff is correct—most tools stop at “diff packages,” not “diff exploitability.”

2) Reachability-driven prioritization (the call-stack explainer)

Instead of ranking by CVSS alone, Stella Ops asks: can our code actually hit the vulnerable sink? Then it shows the minimal path that makes it believable.

What you get:

  • Engineers fix whats actually dangerous first
  • Security can justify prioritization with a “why here?” trace
  • “Unreachable” findings become low-touch (auto-suppress with expiry, or mark as NA with evidence)

This is the difference between “we have log4j somewhere” and “this service calls JndiLookup from a request path.”

3) Evidence-first security: every decision is auditable

Stella Ops can attach cryptographic, machine-verifiable evidence to each conclusion:

  • Diff attestations: what changed between artifact A and B
  • Rescore attestations: inputs used to decide “reachable/not reachable”
  • VEX candidates: “not affected” or “affected” claims with rationale

A clean way to package this is DSSE envelopes (a standard signing wrapper used by supply-chain tooling). DSSE is widely used in attestations and supported in supply chain ecosystems like in-toto and sigstore/cosign. (GitHub)

What you get:

  • Audit-ready trails (“show me why you marked this NA”)
  • Tamper-evident compliance artifacts
  • Less “trust me” and more “verify me”

4) Auto-VEX thats grounded in reality (and standards)

When a vulnerability is present in a dependency but not exploitable in your context, you want a VEX “not affected” statement with a justification—not an ad-hoc spreadsheet.

CISA has documented minimum elements for VEX documents, and points out multiple formats (including CycloneDX/OpenVEX/CSAF) that can carry VEX data. (CISA) CycloneDX specifically positions VEX as context-focused exploitability information (“can it actually be exploited here?”). (cyclonedx.org)

What you get:

  • Fast, standardized “NA” responses with a paper trail
  • Cleaner vendor/customer conversations (“heres our VEX, heres why”)
  • Less time arguing about theoretical vs practical exposure

5) Faster blast-radius answers when a 0day drops

The “smart diff + symbol index + call paths” combo turns incident questions from days to minutes:

  • “Which services contain the vulnerable function/symbol?”
  • “Which ones have a reachable path from exposed entrypoints?”
  • “Which builds/images introduced it, and when?”

Thats an Ops superpower: you can scope impact precisely, patch the right places, and avoid mass-panic upgrades that break production for no gain.

6) Lower total cost: fewer cycles, less compute, fewer human interrupts

Even without quoting numbers, the direction is obvious:

  • Delta rescoring reduces CPU/time and storage churn
  • Reachability reduces triage load (fewer high-severity false alarms)
  • Evidence reduces audit and exception-management overhead

Net effect: security becomes a steady pipeline instead of a periodic “CVE storm.”

7) Better developer UX: findings that are actionable, not accusatory

Stella Ops can present findings like engineering wants to see them:

  • “This new dependency bump added X, removed Y”
  • “Heres the minimal path from your code to the vulnerable call”
  • “Heres the exact commit / layer / symbol change that made risk go up”

That framing turns security into debugging, which engineers are already good at.

8) Standards alignment without being “standards only”

Stella Ops can speak the language auditors and customers care about:

  • SBOM-friendly (CycloneDX is a BOM standard; its also published as ECMA-424). (GitHub)
  • Supply chain framework alignment (SLSA describes controls/guidelines to prevent tampering and improve integrity). (SLSA)
  • Attestations that fit modern ecosystems (DSSE, in-toto style envelopes, sigstore verification).

The advantage is youre not just “producing an SBOM”—youre producing decisions + proofs that are portable.

9) Defensibility: a compounding knowledge graph

Every scan produces structured facts:

  • What changed
  • What functions exist
  • What call paths exist
  • What was concluded, when, and based on what evidence

Over time that becomes a proprietary, high-signal dataset:

  • Faster future triage (because prior context is reused)
  • Better suppression correctness (because its anchored to symbols/paths, not text matching)
  • Better cross-repo correlation (“this vulnerable sink shows up in 12 services, but only 2 are reachable”)

10) “Ops” is the product: governance, exceptions, expiry, and drift control

The last advantage is cultural: Stella Ops isnt just a scanner, its a risk operations system:

  • time-bound suppressions that auto-expire
  • policy-as-code gates that understand reachability and diffs
  • evidence-backed exceptions (so you dont re-litigate every quarter)

A crisp way to pitch it internally

Stella Ops turns vulnerability management from a static list of CVEs into a living, evidence-backed change log of what actually matters—and why. Delta scanning cuts noise, call-stack analysis makes prioritization real, and DSSE/VEX-style artifacts make every decision auditable. (CISA)