bugfix: keep developer backup restores temporary
What changed, and why it matters
This fix corrects a developer-only backup restore feature so that it always creates a temporary wallet when any real wallet secret is already stored on the device. Before the fix, the restore could report success while silently failing to overwrite the active wallet because the operation was treated as a no-op. The change prevents misleading success reports and accidental or malicious overwrites of the real wallet.
Review whether restore_complete() callers elsewhere use the correct guard condition. Consider adding an explicit post-restore verification step that confirms the intended wallet state, and ensure developer-only features cannot be triggered in production builds.
Security signals we found
Logic error in access-control/guard condition
Silent failure / false success report
Developer/debug feature touching wallet restore path
Potential overwrite of active wallet secrets
Evidence from the diff
In shared/actions.py, restore_backup_dev() previously called backups.restore_complete() with the second argument set to not pa.is_secret_blank(). That argument controls whether the restore is routed to a temporary wallet. The old condition only checked if the main PIN/secret area was blank, but did not account for other active secrets (e.g., secondary wallets or seeds). As a result, when a secret was active in another slot, the restore could run against the active wallet, where master writes are no-ops, and still report success. The patch changes the condition to pa.has_secrets(), which is true whenever any secret is active, forcing the restore into a temporary wallet in those cases.
Changed components
shared/actions.pyrestore_backup_dev()backups.restore_complete()Inspect captured patch +3 / −1
### shared/actions.py
@@ -1478,7 +1478,9 @@ async def restore_backup_dev(*a):
if fn:
words = False if fn[-3:] == ".7z" else None
import backups
- await backups.restore_complete(fn, not pa.is_secret_blank(), words)
+ # A temporary wallet makes master writes no-op, despite the restore reporting success.
+ # Route the backup to another temporary wallet whenever any secret is active.
+ await backups.restore_complete(fn, pa.has_secrets(), words)
async def bkpw_override(*A):
# allows user to: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.