security(console): mask key-dump command RESULTS in the scrollback

The console redacted secret command ARGS but showed the OUTPUT of key-revealing
commands (dumpprivkey / z_exportkey / z_exportviewingkey / z_exportmnemonic /
dumpwallet / z_exportwallet, and the lite seed/export verbs) in full — visible
in the scrollback, Copy All, Ctrl+C and the filter. Now, when the submitted
command is key-revealing, its result is held ONLY in a member buffer (never in
the scrollback model, so Copy-All etc. can't leak it) and a masked placeholder
is shown. An explicit "Copy secret" button routes through the auto-clearing
clipboard; the buffer auto-wipes after 60s, on Clear, and on wallet lock
(via wipeDisplayedSecrets). The command string passed to the executor is
byte-identical. New pure helper ConsoleCommandRevealsSecret is unit-testable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 11:39:38 -05:00
co-authored by Claude Opus 4.8
parent 31e9c2ee2c
commit 83ce73f26b
6 changed files with 94 additions and 2 deletions
+3
View File
@@ -162,6 +162,7 @@ void App::wipeDisplayedSecrets()
show_seed_backup_ = false;
sodium_memzero(export_result_, sizeof(export_result_));
ui::KeyExportDialog::hide(); // zeros its static s_key via secureWipeLiteSecret
console_tab_.wipeSecretResult(); // drop any masked key-dump result held in the console
}
// Enqueue a blocking xmrig start/stop op onto the dedicated serialized control thread so the render thread
@@ -2411,6 +2412,8 @@ void App::render()
console_exec_ = std::make_unique<ui::LiteConsoleExecutor>(this);
else
console_exec_ = std::make_unique<ui::FullNodeConsoleExecutor>(this);
// One-time: route the console's "Copy secret" through the auto-clearing clipboard.
console_tab_.setCopySecretHandler([this](const std::string& s) { copySecretToClipboard(s); });
}
console_tab_.render(*console_exec_);
// Persist the console toolbar toggles (ConsoleTab has no settings pointer). Save only when