refuse to display a wallet seed in the terminal when the wallet was locked while its key was derived
What changed, and why it matters
This commit fixes a timing-related issue in Sparrow Wallet's terminal version. If a user asked to view their wallet seed and the wallet auto-locked before the password-derived key was ready, the app could still try to display the seed using a stale/untrusted state. The patch now checks whether the wallet locked during key derivation and refuses to show the seed if so, preventing possible exposure of the seed when the user no longer has an active unlocked session.
Users running the terminal version of Sparrow Wallet should upgrade to a release containing this commit. Reviewers should verify that no other terminal flows similarly use asynchronously derived keys without re-checking the locked state, and consider adding automated tests covering the auto-lock-during-derivation scenario.
Security signals we found
Timing/state synchronization bug in seed display flow
Use of derived key after wallet auto-lock
Potential information disclosure of wallet seed
Defensive guard added to abort on locked state
Evidence from the diff
In SettingsDialog.showSeed(), deriving the encryption key from the password is performed asynchronously via Storage.KeyDerivationService. Because derivation can take long enough for the wallet’s auto-lock to engage, the success handler previously proceeded directly to decrypt and display the seed. The patch adds a check after derivation succeeds: if SparrowTerminal.get().isLocked(getWalletForm().getStorage()) is true, it shows an error dialog and returns before using the derived key. This closes a window where the seed could be shown after the wallet was no longer considered unlocked.
Changed components
src/main/java/com/sparrowwallet/sparrow/terminal/wallet/SettingsDialog.javaSparrow Wallet terminal UI seed display featureStorage.KeyDerivationService asynchronous key derivationInspect captured patch +7 / −0
### src/main/java/com/sparrowwallet/sparrow/terminal/wallet/SettingsDialog.java
@@ -140,6 +140,13 @@ private void showSeed() {
Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(getWalletForm().getStorage(), new SecureString(password), true);
keyDerivationService.setOnSucceeded(workerStateEvent -> {
EventManager.get().post(new StorageEvent(walletId, TimedEvent.Action.END, "Done"));
+
+ //Key derivation takes long enough to lock the wallet while it runs, and a locked wallet is one the password entered before it must no longer open
+ if(SparrowTerminal.get().isLocked(getWalletForm().getStorage())) {
+ showErrorDialog("Wallet Locked", "The wallet was locked before the seed could be displayed.");
+ return;
+ }
+
ECKey encryptionFullKey = keyDerivationService.getValue();
Key key = null;
Why this scored 58/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.