fix(rpc,ui): close the last secret residues found by the final-gate review
Two verified medium leaks in the B7 scrub chain: - parseRpcResult parses the body into a local `response` tree and returns a COPY of response["result"] (operator[] yields an lvalue ref, so the by-value return copy-constructs). The local tree — holding its own heap copy of the secret — was then freed without zeroing, so callSecret/callSecretString still left one un-scrubbed copy. Add scrubJsonSecrets() (recursive string zero) and a scrubSource flag; the secret paths opt in, wiping the tree before it frees. The secret export chain is now fully covered: raw body → parse tree → result copy → caller-owned string. - key_export_dialog cleared s_key with plain std::string::clear() on the Close button, the scrim/Esc dismiss path, and the QR cache (s_qr_cached) — leaving the displayed private/spending key in freed heap on the ordinary close paths. Route all three through wallet::secureWipeLiteSecret (zero-then-clear), matching show()/hide(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,7 @@ std::string KeyExportDialog::s_error;
|
||||
void KeyExportDialog::releaseQr()
|
||||
{
|
||||
if (s_qr_tex) { FreeQRTexture(s_qr_tex); s_qr_tex = 0; }
|
||||
s_qr_cached.clear();
|
||||
wallet::secureWipeLiteSecret(s_qr_cached); // held a plaintext copy of the key for the QR
|
||||
s_show_qr = false;
|
||||
}
|
||||
|
||||
@@ -318,8 +318,8 @@ void KeyExportDialog::render(App* app)
|
||||
|
||||
if (material::TactileButton(TR("close"), ImVec2(button_width, 0), S.resolveFont(closeBtn.font))) {
|
||||
s_open = false;
|
||||
// Clear sensitive data
|
||||
s_key.clear();
|
||||
// Zero the secret, don't just drop the buffer (leaves the key in freed heap otherwise).
|
||||
wallet::secureWipeLiteSecret(s_key);
|
||||
s_show_key = false;
|
||||
releaseQr();
|
||||
}
|
||||
@@ -327,9 +327,9 @@ void KeyExportDialog::render(App* app)
|
||||
material::EndOverlayDialog();
|
||||
}
|
||||
|
||||
// Dialog dismissed any other way (scrim click / Esc): drop the key + its QR texture.
|
||||
// Dialog dismissed any other way (scrim click / Esc): wipe the key + its QR texture.
|
||||
if (!s_open) {
|
||||
if (!s_key.empty()) s_key.clear();
|
||||
wallet::secureWipeLiteSecret(s_key);
|
||||
s_show_key = false;
|
||||
releaseQr();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user