wallet2: fix background wallet detection in verify_password()
What changed, and why it matters
This one-line change fixes a logic bug in how Monero wallets detect 'background wallets' when verifying a password. The old code accidentally treated a JSON parsing failure as evidence that a wallet was a background wallet, and treated successful JSON parsing as evidence it was not. The fix reverses that logic. A background wallet is a special wallet type that lacks a private spend key. Because of the bug, a normal wallet with a valid JSON account record could be misclassified as a background wallet, which could lead the software to skip required spend-key checks or allow operations that should require the spend key. The actual security impact depends on how downstream code uses the no_spend_key flag, but the change clearly corrects an inverted condition that has security-relevant consequences.
Treat this commit as a security-relevant correctness fix. Review all callers and consumers of no_spend_key to confirm the misclassification could not have allowed wallet operations without the spend key, such as signing transactions or exporting key material. Consider requesting or performing a targeted audit of background wallet handling. No immediate emergency response is indicated by the diff alone, but the fix should be included in the next release.
Security signals we found
Inverted boolean condition in security-relevant verification path
Background wallet detection logic tied to spend-key presence
Parse-error result incorrectly treated as positive classification
Potential misclassification of wallet type during password verification
Evidence from the diff
In wallet2::verify_password(), the code decrypts the account_data field and then tries to parse it as JSON. The original line set is_background_wallet to true when json.Parse() had a parse error AND the (uninitialized/empty) json object happened to report IsObject(). The corrected line sets is_background_wallet to true only when parsing succeeds and the result is a JSON object. The flag then feeds into no_spend_key, which controls whether the wallet is treated as having no spend key. The bug meant a corrupted or non-JSON account payload could be classified as a background wallet, while a valid JSON account payload would not be. The patch is minimal and clearly fixes an inverted boolean condition.
Changed components
src/wallet/wallet2.cppwallet2::verify_password()background wallet detectionspend key validationInspect captured patch +1 / −1
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index d7ecd39..d07a7c9 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -5444,7 +5444,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
{
get_custom_background_key(password, key, kdf_rounds);
crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
- const bool is_background_wallet = json.Parse(account_data.c_str()).HasParseError() && json.IsObject();
+ const bool is_background_wallet = !json.Parse(account_data.c_str()).HasParseError() && json.IsObject();
no_spend_key = no_spend_key || is_background_wallet;
}
}
Why this scored 57/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.