CWE-316: Cleartext Storage of Sensitive Information in Memory
Overview
Storing sensitive data (passwords, keys, tokens) in memory as cleartext exposes it to memory dumps, core dumps, swap files, hibernation files, debuggers, and memory disclosure vulnerabilities. Sensitive data should have the shortest practical lifetime, should be cleared from mutable buffers when possible, and should be kept out of dumps and swap for high-risk processes.
OWASP Classification
A06:2025 - Insecure Design
Risk
Medium-High: Cleartext in memory enables data theft via crash dumps, debugger attachment, memory disclosure bugs (Heartbleed), swap file analysis, hibernation file reading, memory scraping malware, and cold boot attacks on RAM.
Remediation Steps
Core principle: Minimize how long sensitive data exists in cleartext memory, avoid unnecessary copies, and use platform protections where they actually apply.
Locate cleartext sensitive data in memory
- Review the flaw details to identify the specific file, line number, and code pattern where sensitive data is stored in memory
- Identify what sensitive data is in memory: passwords, cryptographic keys, tokens, PII
- Trace the data lifetime: where it's loaded into memory, how long it persists, when it's cleared
- Determine exposure risk: can it be swapped to disk, captured in crash dumps, exposed via debuggers
Clear sensitive data after use (Primary Defense)
- Zero mutable buffers containing passwords/keys: Explicitly overwrite memory after use where the language/runtime gives you a mutable buffer (
Arrays.fill(password, '\0')in Java) - Use platform-specific secret containers carefully: Some APIs can reduce exposure, but they often have platform limits and still require plaintext conversion at use boundaries
- Prefer clearable arrays or buffers over strings where the input path allows it: Strings are immutable and cannot be overwritten in place
- Use explicit_bzero() or memset_s() (C/C++): Compiler-safe memory clearing functions (memset can be optimized away)
Prevent memory swapping to disk
- Use
mlock()to lock pages in RAM (Linux): Reduces the chance that selected pages are swapped to disk; check return values and account for process limits - Use
VirtualLock()on Windows where appropriate: Windows equivalent for locking selected pages, subject to working-set and privilege constraints - Mark pages as non-swappable: Use OS-specific APIs for buffers that actually hold the secret, and remember that copies elsewhere may still be swappable
- Disable swap for critical processes when justified: Useful for high-security deployments, but not a substitute for clearing secrets and controlling crash dumps
Use secure memory abstractions
- Use OS or library protected-memory APIs where available: For example, libsodium secure memory can add guard pages, locking, and explicit zeroing
- Use framework secret containers only when their limitations fit your platform: For example, .NET
SecureStringis not recommended for new cross-platform .NET code - Keep long-lived secrets in dedicated key-management services when possible: Prefer vaults, HSMs, cloud KMS, or short-lived tokens over application-managed plaintext keys
Minimize exposure time in memory
- Keep sensitive data in memory briefly: Load just before use, clear immediately after
- Clear immediately after use: Don't let passwords/keys persist longer than necessary
- Don't log sensitive values: Avoid logging passwords, keys, tokens (even to debug logs)
- Avoid string concatenation with secrets: String concatenation creates immutable copies that can't be cleared
Test the memory protection fix
- Verify sensitive data is cleared after use (use debugger to inspect memory, should see zeros)
- Test with memory dump analysis tools to confirm no plaintext secrets in dumps
- Verify memory locking is working (check mlock/VirtualLock calls succeed)
- Test that application doesn't crash from memory locking failures
- Re-scan with security scanner to confirm the issue is resolved
Common Vulnerable Patterns
- Storing passwords in String objects
- Not clearing char[] after use
- Logging sensitive data
- Sensitive data in immutable strings
- Not locking memory pages
Language-Specific Guidance
For detailed implementation guidance and code examples in your programming language:
- Python - Using
bytearray,mlock, context managers, and secure framework patterns - Java - Using
char[],Arrays.fill(),AutoCloseable, and Spring Security trade-offs - JavaScript/Node.js - Using
Buffer,fill(0),crypto.timingSafeEqual(), and Express/Next.js patterns - C# - Using
Array.Clear(),SafeHandle, cautiousSecureStringhandling, and ASP.NET Core Data Protection