This weakness occurs when sensitive data—such as passwords, API keys, authentication tokens, or personal information—is stored in a way that does not adequately protect it from unauthorized access. This includes storing data unencrypted, using weak encryption, storing it in world-readable files, or failing to restrict database access. The result is that an attacker who gains even limited access to the system can easily retrieve and misuse that data.
02How It Happens
Sensitive information becomes vulnerable when developers prioritize convenience over security during storage. Common patterns include hardcoding secrets in source code or configuration files, storing passwords in plaintext in databases, writing API keys to log files, or saving sensitive data in temporary directories with default permissions. The weakness often stems from a misunderstanding of what "sensitive" means, insufficient threat modeling, or pressure to ship quickly without implementing proper encryption and access controls. Even when encryption is used, weak algorithms, poor key management, or reused keys across multiple secrets can render the protection ineffective.
03Real-World Impact
Compromised sensitive data can lead to account takeover, unauthorized API access, lateral movement within a network, and exposure of personal information. If database credentials are stored insecurely, an attacker who breaches one system can use those credentials to access the database directly, potentially exposing thousands of records. Leaked API keys or authentication tokens allow attackers to impersonate legitimate users or services. In regulated industries, insecure storage of personal data can trigger compliance violations and significant fines.
04Vulnerable & Fixed Patterns
Vulnerable pattern
import sqlite3
# Storing API key in plaintext in source code
API_KEY = "sk_live_abc123xyz789"
# Storing password in plaintext in database
conn = sqlite3.connect("app.db")
cursor = conn.cursor()
username = "admin"
password = "MyPassword123" # plaintext
cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)",
(username, password))
conn.commit()
Why it's vulnerable: Hardcoding secrets in source code and storing passwords as plaintext in the database means anyone with access to the code repository or database can immediately read and misuse them.
Fixed pattern
import sqlite3
import os
from werkzeug.security import generate_password_hash
# Load API key from environment variable
API_KEY = os.getenv("API_KEY")
if not API_KEY:
raise ValueError("API_KEY environment variable not set")
# Hash password before storing
conn = sqlite3.connect("app.db")
cursor = conn.cursor()
username = "admin"
password = "MyPassword123"
hashed_password = generate_password_hash(password)
cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)",
(username, hashed_password))
conn.commit()
Vulnerable pattern
<?php
// Storing database credentials in plaintext in config file
$db_user = "root";
$db_pass = "password123";
$db_host = "localhost";
// Storing API key in plaintext in database
$api_key = "sk_live_abc123xyz789";
$wpdb->insert('api_keys', array('key' => $api_key, 'user_id' => 1));
// Writing sensitive data to log file
error_log("User login attempt with password: " . $_POST['password']);
?>
Why it's vulnerable: Plaintext credentials in configuration files, unencrypted secrets in the database, and sensitive data in logs are all easily accessible to anyone with file system or database access.
Fixed pattern
<?php
// Load credentials from environment variables
$db_user = getenv('DB_USER');
$db_pass = getenv('DB_PASSWORD');
$db_host = getenv('DB_HOST');
if (!$db_user || !$db_pass) {
throw new Exception('Database credentials not configured');
}
// Hash and store API key securely
$api_key = "sk_live_abc123xyz789";
$hashed_key = hash('sha256', $api_key);
$wpdb->insert('api_keys', array('key_hash' => $hashed_key, 'user_id' => 1));
// Log only non-sensitive information
error_log("User login attempt for account: " . sanitize_text_field($_POST['username']));
?>
05Prevention Checklist
Use environment variables or secure vaults for all secrets (API keys, database credentials, tokens); never hardcode them in source code or configuration files.
Hash passwords using a strong, modern algorithm (bcrypt, Argon2, scrypt) before storing them; never store plaintext passwords.
Encrypt sensitive data at rest using strong encryption (AES-256) with properly managed keys; store encryption keys separately from encrypted data.
Restrict file and database permissions so that only necessary processes and users can read sensitive data; audit access regularly.
Avoid logging sensitive information such as passwords, tokens, or personal data; log only what is necessary for debugging and monitoring.
Rotate secrets regularly and implement a process to revoke compromised credentials quickly.
06Signs You May Already Be Affected
Review your codebase and configuration files for hardcoded API keys, database passwords, or other secrets. Check database tables for plaintext passwords or unencrypted sensitive fields. Examine log files for accidental inclusion of passwords, tokens, or personal information. If you find any of these, assume they may have been exposed and rotate those credentials immediately.