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.
12 KiB
12 KiB