CWE-313: Cleartext Storage in a File or on Disk
Overview
Storing sensitive data (passwords, API keys, PII, credit cards, session tokens) unencrypted in files or databases means anyone who reaches that storage reads it directly. The routes are backup exposure, filesystem access, database dumps, stolen laptops or servers, and insider access.
Relationship to Other CWEs
- CWE-313 (this page) - The specific case where cleartext sensitive data is written to a file or disk: config files, database files, logs, backups. Use this page when a finding points to a file write, database column, or disk-persisted artifact.
- CWE-312 (Cleartext Storage of Sensitive Information) - The broader parent category, covering cleartext storage in any medium, including cloud storage and version control, not just local files or disk.
- CWE-316 (Cleartext Storage of Sensitive Information in Memory) - A different storage medium entirely, in-process memory rather than disk. Use that page for memory dumps, swap files, and debugger exposure.
OWASP Classification
A06:2025 - Insecure Design
Risk
High: Cleartext storage exposes sensitive data in backups, database dumps, log files, config files, stolen devices, and filesystem snapshots. Whoever reads one of those gets the credentials, payment card data, and PII as they stand, with no further work needed.
Compliance exposure: Breaches PCI DSS requirements for stored cardholder data outright. HIPAA treats encryption at rest as addressable and GDPR Article 32 is risk-based, so the exposure there is failing a control your own risk assessment called for - which is harder to argue away, not easier. CCPA does not mandate encryption at all: California Civil Code Sec. 1798.150 makes "nonencrypted and nonredacted" personal information the trigger for the statutory private right of action after a breach, so what cleartext storage costs you is the safe harbour, not compliance.
Remediation Steps
Core Principle: Never store sensitive data in files on disk in cleartext; encrypt and limit access with least privilege.
Locate the cleartext storage in files or on disk
- Find the file, line, and code path where sensitive data is stored without encryption
- Identify what is stored: passwords, API keys, PII, credit cards, session tokens
- Identify where it lands: database files, configuration files, log files, temporary files, backups
- Follow the data to the write: where it reaches disk and in what format
Encrypt sensitive data at rest (Primary Defense)
- Use AES-256-GCM, an authenticated cipher, for symmetric encryption of data at rest
- Keep keys in a key management system such as AWS KMS, Azure Key Vault, GCP KMS, or HashiCorp Vault, never alongside the encrypted data
- Encrypt sensitive database columns at the application level. Database-level encryption (TDE) protects the stored files from a stolen disk or medium and decrypts for any authorized connection, so it complements column encryption rather than replacing it. A logical export (
mysqldump,pg_dump,bcp) of a TDE-protected database contains plaintext, because it leaves through the SQL layer that TDE decrypts for - Add full disk encryption for the underlying storage as defense in depth: BitLocker on Windows, FileVault on macOS, LUKS on Linux
Use proper key management
- Store keys separately from the data they protect: a different server, service, or KMS
- Use a cloud KMS (AWS KMS, Azure Key Vault, GCP KMS) for centralized key management with access control and audit logging
- Rotate keys on a schedule, annually or after a security incident, and automate rotation where possible
- Use separate keys for dev, staging, and production, and separate keys per tenant in multi-tenant systems
Hash instead of encrypt (when appropriate)
- Passwords: hash with bcrypt or Argon2id, never encrypt. Use current OWASP guidance as a floor, tune parameters on production hardware, and plan periodic cost increases
- Tokens: if you only need to verify them, store a hash and look up by the hash rather than the plaintext
- API keys: the same applies if authentication only needs to verify them
- Encrypt only data that must be read back in plaintext, such as credit cards for refunds or PII for display
Minimize storage of sensitive data
- Do not store sensitive data unless a business function requires it
- Truncate credit cards: store only the last four digits,
****-****-****-1234, instead of the full number - Tokenize payment data: hold a Stripe, PayPal, or payment gateway token instead of the card number
- Delete sensitive data when it is no longer needed, with retention policies and automated purging
Test the encryption implementation
- Inspect the files and database directly and confirm they hold ciphertext, not plaintext
- Confirm decryption works for legitimate access
- Confirm keys are held in a different service, KMS, or vault from the encrypted data
- Confirm backups are encrypted too, and that restore preserves the encryption
- Confirm file permissions are restrictive (600 or 640, not world-readable)
- Re-scan with security scanner to confirm the issue is resolved
Common Vulnerable Patterns
- Passwords stored so that they can be recovered - written as plaintext, obfuscated with base64 or a home-grown transform, or encrypted with a key the application holds. The column type is not the tell: a bcrypt or Argon2id digest lives in a
VARCHARperfectly correctly. What is wrong is anything a database dump can be turned back into the user's password. See CWE-916 for the hashing requirement - API keys in config files, checked into version control or baked into a deployed image
- Credit cards in plaintext columns
- Session tokens stored as issued, so a database dump hands the attacker working sessions. Encryption is not the control here - the server never needs the token back, only to recognise it, so store a hash of the token and compare against that, as under "Hash instead of encrypt" above
- PII without encryption