fix: wipe the exported private key from the DOM on leaving the screen (closes #221)
All checks were successful
check / check (push) Successful in 27s

The export screen registered no view-leave cleanup, so leaving it by any
route other than its own Back button — the settings gear, for instance —
left the decrypted private key in #export-privkey-value inside the hidden
view for the rest of the popup's life. The reveal path had the same
post-await hole the recovery phrase screen had: the write landed after
the wipe, with nothing scheduled to wipe it again.

The screen moves out of addressDetail.js into its own module shaped like
showPhrase.js: onViewLeave() cleanup that wipes the value node, the
password input and the closure state, and a revealGeneration liveness
guard captured before the decrypt. The guard sits in front of the key
derivation, so a decrypt that resolves after the screen was left does not
even derive the key.

The audit for the same bug class covered every other screen holding
secret material in the DOM. AddWallet (a generated or pasted recovery
phrase, an imported private key or extended private key, and the
password) and the password inputs on ConfirmTx, DeleteWallet, ApproveTx
and ApproveSign were all cleared on entry only, so each survived in its
hidden view after the screen navigated on. All five now register the same
cleanup. None of them writes a secret after an await, so none needs a
generation guard.

The load-bearing test leaves the screen mid-decrypt and asserts the key
never lands in the DOM, and that it still does not land once the user has
returned to the screen — which the generation counter catches and a
current-view check alone would not.
This commit is contained in:
2026-08-12 08:26:16 +00:00
parent bd4bdcafc7
commit 374b4bbce6
9 changed files with 607 additions and 87 deletions

View File

@@ -44,6 +44,12 @@ undefined identifiers, which is how
# Completed Steps
- 2026-08-12: The private key export screen now wipes the key from the page
whenever it is left by any route, and a decrypt still in flight when the
screen is left is discarded instead of written; the same `onViewLeave()`
cleanup was extended to every other screen holding secret material in the DOM
(AddWallet, ConfirmTx, DeleteWallet, ApproveTx, ApproveSign)
([#221](https://git.eeqj.de/sneak/AutistMask/issues/221)).
- 2026-08-12: An xprv wallet already in storage that was imported from a
non-master key is detected from the depth of its stored `xpub`, explained in
the wallet list, and blocked from signing, sending and private-key export