fix(triage): withdraw the disproven false positives and render deployed-vs-pinned versions #22
Loading…
Reference in a new issue
No description provided.
Delete branch "fm/dse-security-reports-defender-evidence-correction"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The 28.10.2026 verification round (firstmate report
dse-security-reports-pyjwt-qms-verify) found Defender's pyjwt claim real: packages the report declared absent are installed in root-only Ricochet deployment stores, so the report reassured about a real finding and the "unreliable Linux evidence" reasoning built on that had to be reworked, not trimmed. This PR retracts three of the five 26.10 false-positive confirmations on that evidence (pyjwt, anyio, h11), re-titles and re-sorts the affected section, and renders the deployed-versus-pinned package versions deterministically from the pipeline instead of as a hand-read snippet — plus the two folded-in corrections from the same verification round: the security-check failure cause per unit instead of a collapsed "error", and the WireGuard sensor facts instead of the "coverage gap" inference.What changed
.local/samples/triage.csv(not committed; re-applied per round) — the FalsePositive annotations for CVE-2026-102268 (pyjwt), CVE-2026-63374 (anyio) and CVE-2025-43859 (h11) are removed; pillow and OpenSSL-Windows stay.reports/defender-triage.typ— the section «Warum die Linux-Evidenz von Defender unzuverlässig ist» is replaced by «Linux-Paketevidenz: Korrektur der Bewertung (Verifikation 28.10.2026)»: per-package verified position, mechanisms re-sorted with our own collection coverage failure as the root mechanism, and the index-accumulation mechanism kept but its failed inference named. The FP section carries the withdrawal record (the 26.10 confirmations rested on analysis since disproven; remaining candidates: pillow, OpenSSL). New section «Deployt vs. gepinnt» renders the per-unit/per-package table from the derive. New subsections under Evidenzabdeckung: «Sicherheits-Update-Check je Einheit» (status, reason, repo; error carries no count) and «Defender-Sensor je Einheit» (mdatp health, WireGuard onboarding verified, stale definitions and passive mode as explicit findings). The ranking column becomes «Linux-Boden-Evidenz» with inverted polarity, P15's security-check sentence and the P6/P8/P9/P10 analyses are corrected, the WireGuard "coverage gap" framing is replaced by the verified sensor facts, and the Fan-out rows 5/8 are updated.scripts/derive_findings.py+src/dse_security_reports/derive.py(mirrored, byte-identical on the fixture) — store normalization across the three cache shapes (legacy pyjwt paths, per-package dist-info paths, verified aggregated counts with asweptlist), a partial sweep makes no claim;ricochet_aggregatejoins Defender claims, the committed lock pins, store versions and running deployments into the payload-levelricochetblock;patch_posturerecords the security-check reason/repo and nulls the update count under error;defender_coveragepasses the mdatp health block through.config/app-locks.json(new, committed) — lock pins of the deployed application projects (tracking-quality, myride_simulation) with provenance (read date, last-committed date, deploy member lock); the drift story (root 2.15.1/1.39.0/1.44.2 vs app 2.13.0/1.36.0/1.41.0, deployment resolves from the June-pinned app lock) and the myride contrast (locks agree, deployment faithful) render from it.scripts/ssh_evidence.sh— the ricochet sweep covers all four tracked packages (pyjwt, anyio, h11, pillow), the mdatp probe gains a read-onlysudo -n mdatp healthsection (with a health-only refresh for caches that predate it), and the security-check parser records which repository failed and why instead of collapsing to a single word.scripts/backfill_verified_evidence.py(new) +just backfill-verified— idempotent merge of the verified 28.10 probe results (store facts, mdatp health, sec-check reasons) into a restored 2026-10-27 evidence cache; the collector writes the same shapes in future rounds, so the bridge retires itself.tests/test_derive.py— the ricochet tests move to the aggregated entry shape, cover the verified-backfill shape (swept list, un-swept packages make no claim), running-deployment resolution, the deployment-vs-pins aggregate with its gap states, the null update count under error, and the health block pass-through.AGENTS.md,README.md,Justfile— the correction round, the backfill recipe and the app-locks config are documented; the published-round restoration protocol gains the backfill step.Behaviour change
The re-rendered 27.10 round (published to the firstmate artifacts dir as
defender-triage-2026-10-28.pdf/defender-findings-2026-10-28.pdf, previous copies moved tosuperseded/, the 2026-10-26 set untouched) states the corrected position: three false-positive confirmations withdrawn, the QMS pyjwt row derivestrivy-silentfrom the store evidence (the only scanner-agreement change; verified against an isolated origin/main re-derivation — every other number is unchanged), the deployed-versus-pinned table replaces the hand-read snippet, a refused or un-swept store always renders as a gap never as an absence, and the WireGuard unit renders as sensor-verified onboarded with its index below the export thresholds instead of as a Defender coverage gap.Section-title decision (asked for in the task)
The old title claimed Defender's Linux evidence was unreliable; the verification shows the opposite where it could check: Defender's package-and-version quotes were real (pyjwt running in production on QMS, anyio/h11 in every myride bundle, the workbench versions in colleague venvs), while our own collection was the unreliable part (root-only stores, silently skipped subtrees, unreadable colleague homes). The new title «Linux-Paketevidenz: Korrektur der Bewertung» therefore names the correction instead of prejudging either side; the same reasoning renamed the ranking column to «Linux-Boden-Evidenz» (polarity inverted: evidence-backed rows read "ja (Evidenz)", index-only rows "nein (Index)"). What remains true about Defender — over- AND under-reporting at the same time (silent on the identical myride stack, silent on the kernel CVEs) — is kept as a mechanism, not a verdict.
Consideration asked for in the follow-up instruction: sudo and the security check
Running
dnf --security check-updatewith read-only sudo would NOT sidestep the failure: the abort is a GPG key-trust question (packages-microsoft-com-prod carries no trusted signing key, dnf attempts an interactive key import, finds no terminal), not a permission question — and auto-importing keys during an evidence run would be a silent trust decision, not evidence. The actual fix is provisioning the repo's signing key via config management (gpgkey in the repo definition), an estate change that belongs to the captain; the check therefore stays exactly as it runs today, and this PR only records what failed, per unit, and never reads the accompanying 0 as a count.Instructions-PR: none