Skip to content

CWE-312: Cleartext Storage of Sensitive Information

Overview

Cleartext storage occurs when applications store sensitive information without encryption, making it readable to anyone who gains access to the storage medium. Unlike cleartext transmission (CWE-319), this vulnerability affects data at rest - in databases, files, logs, cache, backups, and memory dumps.

Common examples include unencrypted credentials (passwords, API keys), personal information (SSN, health records), financial data (credit cards), and cryptographic keys stored in databases, configuration files, logs, cloud storage, or version control systems.

OWASP Classification

A06:2025 - Insecure Design

Risk

Cleartext storage creates severe data breach risks:

  • Data breaches: Database compromises expose all sensitive data immediately
  • Insider threats: DBAs, developers, support staff can read sensitive data
  • Backup exposure: Backup tapes, dumps, snapshots contain unencrypted data
  • Cloud misconfig: S3 buckets, Azure blobs with sensitive data publicly accessible
  • Compliance violations: Fails PCI-DSS, HIPAA, GDPR, SOC 2 encryption requirements
  • Credential theft: Stolen API keys, passwords enable further compromise
  • Identity theft: Exposed PII enables fraud and identity theft
  • Ransomware impact: Attackers exfiltrate unencrypted data before encryption
  • Legal liability: Fines, lawsuits, mandatory breach disclosure

Unencrypted database dumps are prime targets in ransomware attacks for extortion.

Common Vulnerable Data and Storage Locations

Sensitive data commonly stored insecurely:

  • Credentials: Passwords, API keys, secret tokens, private keys
  • Personal information: SSN, passport numbers, dates of birth, addresses
  • Financial data: Credit card numbers, bank accounts, payment tokens
  • Health records: Medical history, diagnoses, prescriptions (PHI/ePHI)
  • Cryptographic keys: Encryption keys, signing keys, certificates
  • Session data: Authentication tokens, session identifiers
  • Business secrets: Proprietary algorithms, pricing data, customer lists

Storage locations vulnerable to cleartext exposure:

  • Databases (primary and backup)
  • Configuration files
  • Log files
  • Temporary files and cache
  • Memory dumps and swap files
  • Version control systems
  • Cloud storage buckets
  • Mobile app local storage

Remediation Steps

Core principle: Do not persist sensitive information in cleartext; encrypt recoverable sensitive data, hash passwords with password-hashing algorithms, tokenize where possible, and redact data that does not need to be stored.

Locate the cleartext storage of sensitive data

  • Review the flaw details to identify what sensitive data is stored without encryption
  • Identify storage locations: database columns, configuration files, log files, cache, temporary files, cloud storage
  • Determine data type: credentials (passwords, API keys), PII (SSN, passport), financial (credit cards), health records (PHI), cryptographic keys
  • Trace the data flow: where data is written and how it's stored

Encrypt sensitive data at rest (Primary Defense)

  • Database encryption: Use transparent data encryption (TDE) for broad storage protection and application-level or column-level encryption for fields that must remain protected from database dumps or broad database access
  • File encryption: Encrypt files before writing to disk using authenticated encryption such as AES-GCM or ChaCha20-Poly1305; avoid sensitive information in file names
  • Cloud storage encryption: Enable server-side encryption (AWS S3: SSE-KMS, Azure: Storage Service Encryption, Google Cloud: default encryption at rest)
  • Key management: Store encryption keys separate from data, use key management services (AWS KMS, Azure Key Vault, HashiCorp Vault), rotate keys regularly
  • Never hard-code keys: Use envelope encryption (encrypt data keys with master key)

Use application-level encryption for sensitive database fields

  • Encrypt before storing: encryptedData = encrypt(sensitiveData, encryptionKey) then db.execute("INSERT INTO users (ssn_encrypted) VALUES (?)", encryptedData)
  • Use authenticated encryption: AES-GCM, ChaCha20-Poly1305, or another vetted AEAD mode; generate a unique nonce for each encryption under the same key
  • Consider searchability: Use tokenization, keyed hashes for exact-match lookup, or carefully reviewed searchable-encryption designs if you need to search protected data
  • Do NOT encrypt passwords: Use bcrypt/Argon2/scrypt (hashing, not encryption) for passwords
  • Format-preserving encryption: Use FPE only when compatibility requires it and after reviewing the leakage and compliance tradeoffs

Minimize storage of sensitive data

  • Use tokenization: Store tokens instead of credit cards (use payment gateway tokens like Stripe, PayPal)
  • Just-in-time data: Request data when needed, don't persist, use session-only storage, clear after use
  • Redaction: Store only the display-safe portion of data, such as the last 4 digits of a card; use keyed hashes or tokens for lookup instead of plaintext
  • Retention policies: Delete sensitive data after the required retention period, automate purging of old records, and use cryptographic erasure or controlled backup expiry where direct deletion from backups is not practical

Secure logs and temporary storage

  • Never log sensitive data: Don't log passwords, tokens, credit cards, PII, session IDs (or redact them)
  • Sanitize error messages: Don't include sensitive data in exceptions or stack traces
  • Secure temporary files: Avoid writing sensitive data to shared temp directories; if unavoidable, encrypt temp files, use restrictive permissions, and delete them as soon as possible
  • Memory protection: Avoid memory dumps with sensitive data and clear sensitive buffers where the language/runtime gives reliable control

Test the encryption implementation thoroughly

  • Verify sensitive data is encrypted in storage (inspect database, files to confirm ciphertext)
  • Test decryption works correctly for legitimate access
  • Verify keys are stored separately from encrypted data
  • Check logs don't contain sensitive plaintext data
  • Test backup/restore process maintains encryption
  • Re-scan with security scanner to confirm the issue is resolved

Secure Patterns

Logging Best Practices

// GOOD - Sanitized logging
logger.info("User login attempt: " + username);
logger.debug("Payment processed: card ending " + ccNumber.substring(ccNumber.length() - 4));
logger.error("Query failed: INSERT INTO users (ssn) VALUES ('***')");

Log filtering:

  • Use log filters to scrub sensitive patterns
  • Redact credit cards: (\d{4}[-\s]?){3}\d{4}
  • Redact SSN: \d{3}-\d{2}-\d{4}
  • Redact API keys, tokens, passwords from logs
  • Never log request bodies containing sensitive data

Temporary Files Best Practices

Temporary file security:

  • Encrypt temp files containing sensitive data
  • Use secure temp directories with restricted permissions
  • Delete immediately after use
  • Avoid shared temporary directories such as /tmp for sensitive data unless file permissions and lifecycle controls are explicit

Testing & Verification

Database Inspection

-- Check database for cleartext sensitive data
SELECT password, api_key, ssn, credit_card 
FROM users 
LIMIT 10;

-- Expected: 
-- Passwords are hashed (not encrypted): $2b$12$...
-- Other fields are encrypted: binary/base64 gibberish
-- OR tokenized: tok_1234567890
-- NOT plaintext: "password123", "4111-1111-1111-1111"

Log File Audit

# Search logs for sensitive data patterns
grep -r "password" /var/log/app/
grep -r "[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\}" /var/log/  # SSN pattern
grep -r "[0-9]\{4\}[- ][0-9]\{4\}[- ][0-9]\{4\}[- ][0-9]\{4\}" /var/log/  # CC pattern

# Expected: No matches or only redacted versions (***-**-1234)

File System Check

# Check for sensitive data in config files
cat config/database.yml  # Should not contain committed plaintext passwords
cat .env  # Should not be committed to git; prefer a secrets manager for deployed systems
find . -name "*.key" -o -name "*.pem"  # Private keys should be encrypted or tightly access-controlled

# Check file permissions
ls -la config/ logs/ tmp/

# Expected: Restrictive permissions (600 or 640), not world-readable

Backup and Export Testing

# Create database backup
mysqldump -u root -p database > backup.sql

# Inspect backup file
grep -i "credit_card\|ssn\|password" backup.sql

# Expected: 
# - Passwords are hashed
# - Sensitive fields are encrypted (binary data or base64)
# - NOT plaintext sensitive values

Cloud Storage Verification

# AWS S3 encryption check
aws s3api head-object --bucket mybucket --key sensitive-file.txt

# Expected: ServerSideEncryption: AES256 or aws:kms

# Check bucket public access
aws s3api get-bucket-acl --bucket mybucket

# Expected: No public access grants

Additional Resources