fix(wasm): impl Drop for SessionHandle clears registry entry

Closes the P1.1 defense-in-depth gap: wasm-bindgen's auto-generated
.free() previously dropped the SessionHandle wrapper (a u32) without
removing the SESSIONS HashMap entry, leaving the master key and
image_secret in WASM linear memory until JS explicitly called
lock(handle). Drop now wires .free() to session::remove, and the
new native test pins the contract.

Refs: docs/superpowers/specs/2026-05-04-security-polish-design.md (Phase 1)
Refs: docs/superpowers/reviews/2026-05-04-architecture-review.md (P1.1)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-05-06 01:52:24 -04:00
parent bd3d53fddb
commit 1e858e1d1f
3 changed files with 56 additions and 1 deletions

View File

@@ -46,6 +46,9 @@ where
SESSIONS.with(|s| s.borrow().get(&handle).map(|d| f(&d.image_secret)))
}
/// Remove a session entry. Called by both `lock(handle)` (the explicit
/// path) and `impl Drop for SessionHandle` (the safety net). Returns
/// `true` if an entry was removed, `false` if the handle was already gone.
pub fn remove(handle: u32) -> bool {
SESSIONS.with(|s| s.borrow_mut().remove(&handle).is_some())
}