diff --git a/design/security-review-2026-06-28.md b/design/security-review-2026-06-28.md index d04a78f..25c4991 100644 --- a/design/security-review-2026-06-28.md +++ b/design/security-review-2026-06-28.md @@ -12,6 +12,39 @@ > completeness. No memory-unsafety or RCE on attacker wire bytes was found; the residual risk is in > dependency hygiene, the opt-in GameStream surface, and Windows local-privilege ACLs. +## Remediation status (2026-06-28) + +Fixes landed on `main` in `3532e35` (Linux/cross-platform, cargo check/clippy/test green here) and +`6f903f7` (Windows `#[cfg(windows)]` DACL paths — verify in CI / on the RTX box; this Linux dev VM +can't compile MSVC). Items whose fix would risk a validated pipeline, or that have no upstream +remedy, are deferred/accepted with a reason. + +| # | Sev | Status | +|---|-----|--------| +| S1 | High | **FIXED** (`3532e35`) — `quinn-proto` → 0.11.15 (RUSTSEC-2026-0185) | +| #1 | High | **FIXED** (`3532e35`) — unauthenticated nvhttp `GET /pin` removed; PIN only via bearer mgmt API | +| #2 | High | **FIXED** (`6f903f7`, *Win CI/box pending*) — mgmt token written via `write_secret_file` (SYSTEM/Admins DACL) | +| #3 | High | **FIXED** (`6f903f7`, *Win CI/box pending*) — config dir DACL-locked + re-owned; `host.env` locked. Residual: a host.env planted before the very first DACL apply is still loaded (an owner-check on load is a noted follow-up) | +| #4 | High→Med | **FIXED** (`3532e35`) — RTSP/PLAY gated on a paired `/launch` + bound to the launching peer's IP | +| #5 | Med | **DEFERRED** — the shared-section SDDL is permissive for a restricted-token UMDF driver; scoping it needs on-box validation to avoid breaking the live-validated gamepad/IDD pipeline | +| #6 | Med | **FIXED** (`3532e35`) — EIS relay moved to `$XDG_RUNTIME_DIR` (0700) + symlink reject | +| #7 | Med→Low | **FIXED** (`3532e35`) — `vdisplay::ENV_LOCK` serializes setup-path env mutation (data-race UB closed); full per-session `SessionContext` threading for value-confusion is a follow-up | +| #8 | Low | **FIXED** (`6f903f7`, *Win CI/box pending*) — web-password file created empty → locked → written | +| #9 | Low | **ACCEPTED** — disarm-on-any-attempt IS the documented single-online-guess (prior-fix #2); the delegated-approval flow is structurally immune. Steer hostile LANs to it | +| #10 | Low | **FIXED** (`3532e35`) — ENet decrypt-failed warn throttled (exponential) | +| #11 | Low | **FIXED** (`6f903f7`, *Win CI/box pending*) — logs dir DACL-locked (subsumed by #3) | +| #12 | Low/Info | **FIXED** (`3532e35`) — parked pairing-waiter cap (+regression test) | +| #13 | Info | **ACCEPTED** — `PENDING_CAP` + LRU + `requested_at` refresh make an actively-retrying device non-evictable | +| S2 | Low–Med | **FIXED** (`3532e35`) — a malformed Opus frame drops the frame, keeps the shared mic open | +| S3 | Low | **FIXED** (`3532e35`) — held buttons/keys are capped `HashSet`s | +| S4 | Low | **FIXED** (`3532e35`) — Epic launcher-cache reads size-capped | +| S5 | Low→Info | **FIXED** (`3532e35`) — `fps==0`/absurd rejected at the `open_video` chokepoint | +| S6 | Low→Info | **FIXED** (`3532e35`) — shared mic mpsc bounded (drop-newest) | +| S7 | Low→Info | **ACKNOWLEDGED** — `rsa 0.9` Marvin has no fixed upstream release; GameStream is off by default and this is a signing (not decryption-oracle) path. Migrate the GameStream identity to Ed25519/ECDSA when feasible | + +**Net:** 14 of 18 fixed (5 Linux-verified clusters + 4 Windows DACL paths awaiting CI/box); #5 +deferred pending on-box validation; #9/#13 accepted-with-rationale; S7 acknowledged (no upstream fix). + ## Consolidated overview & top priorities The host's **core trust architecture remains sound**: native SPAKE2 pairing (single-use