b542106c76b2e496a7f3c7b65c8d555e08639a8b
A memory dump of the WebView2 renderer (vault unlocked) showed the AES vault key sitting in sessionStorage as a clean base64 string — a plaintext copy of the master secret, trivially grep-able, present the whole session. persistCryptoKey/restoreCryptoKey existed only to survive a page reload, but the shell has no reload path (F5/Ctrl+R blocked, every navigation is a cmd:// bridge call), so the branch that consumed it was unreachable. Removed both functions, their 7 call sites, and collapsed the init restore branch into the plain cold-start path (Quick Unlock → PIN → master-pw, all already there). Also scrub the derived key bytes from the heap (keyBytes.fill(0)) once the CryptoKey and verifier are built — the CryptoKey keeps its own copy. Not fixable here, documented: the key stays extractable:true (Quick Unlock, PIN, recovery and master-pw change all exportKey it), and decrypted password strings still linger in the V8/Blink heap after lock — immutable strings the GC never zeroes, inherent to a JS/WebView2 password manager. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
full local password manager
Languages
Pascal
46.7%
JavaScript
35.4%
HTML
9.4%
CSS
4.9%
PHP
2.1%
Other
1.4%