CWE-1258 is about hardware that does not fully clear security-sensitive values, such as keys and intermediate results of cryptographic operations, when debug mode is entered. Anyone designing SoCs with cryptographic cores is affected. The MITRE record also lists a software case, debug logs that leak credentials, so developers should read on too.
How it happens
Keys and intermediate steps of cryptographic work are stored in temporary registers in the hardware. Normally software and other untrusted agents are blocked from them. The debug and test interface is a separate path. If the registers are not cleared when the system enters debug mode, a debugger can read them, and the debugger may be run by an untrusted party.
MITRE's example is a cryptographic core on a SoC that handles AES, SHA-256, HMAC and similar operations. Its internal registers sit in memory-mapped I/O space and are blocked from software. They are still reachable through the debug and test interface, and they are not cleared on entering debug. An untrusted actor running a debugger can read secret keys and other sensitive cryptographic information.
Two observed examples are in the record. CVE-2021-33080 covers uncleared debug information in a memory accelerator for an SSD product, exposing sensitive system information (Gold page). CVE-2022-31162 is a Rust library that leaks OAuth client details in application debug logs (Gold page). Different layers, same shape: a debug path that carries more than it should.
What an attacker gains
The record lists confidentiality, through reading memory, and bypassing protection mechanisms. A leaked key defeats the cryptography that depended on it.
How to find it
The record lists no detection methods. Useful checks:
- List every register that holds keys or intermediate cryptographic values.
- Attach a debugger as an untrusted party and try to read each register on entering debug.
- For software, run with debug logging on and search the output for tokens, keys and client secrets.
How to fix it
MITRE's mitigation, at design: whenever debug mode is enabled, clear all registers that contain sensitive assets.
For the software variant, the same principle applies to debug output. Do not let secrets be printed by default formatting. In Rust, a hand written Debug implementation can redact a field:
use std::fmt;
struct Client {
id: String,
secret: String,
}
// Vulnerable: derive(Debug) would print the secret in logs.
impl fmt::Debug for Client {
// Fix: write a redacted value instead of the real one
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Client")
.field("id", &self.id)
.field("secret", &"[redacted]")
.finish()
}
}
Try it yourself
Secrets that end up in logs and configuration are what a secrets scan looks for. This demo shows how a scan reports them.
Click through it at your own pace, or open it full screen.
Quick check
What should happen to key registers when debug mode begins?
They must be cleared, so a debugger cannot read the keys or intermediate values.
How does the software example relate?
CVE-2022-31162 leaked OAuth client details through debug logs, the same pattern of a debug path exposing secrets.