Improper Removal of Sensitive Information Before Storage or Transfer
This weakness occurs when sensitive data—such as passwords, API keys, authentication tokens, or personal information—is stored, cached, or transmitted without…
This weakness occurs when sensitive data—such as passwords, API keys, authentication tokens, or personal information—is stored, cached, or transmitted without being properly removed or redacted first. The data ends up accessible to people who should never see it, either because it's left in logs, temporary files, backups, or transmitted in plain text. It's a common root cause of data breaches and credential theft.
02How It Happens
Developers often focus on the happy path: accepting user input, processing it, and returning a result. Sensitive data gets logged for debugging, cached for performance, or included in error messages for troubleshooting—without considering who might later read those logs, access the cache, or see the error output. Similarly, data may be transmitted over unencrypted channels or stored in backups without encryption, assuming only authorized systems will ever touch it. The weakness emerges when that assumption breaks: a log file is accidentally exposed, a backup is restored to the wrong environment, a cache is readable by another application, or a network packet is intercepted.
03Real-World Impact
Exposed credentials allow attackers to impersonate legitimate users or systems, leading to account takeover, lateral movement, and privilege escalation. Leaked personal information (names, emails, phone numbers, addresses) fuels identity theft and phishing campaigns. Exposed API keys or database connection strings give attackers direct access to backend systems. In regulated industries, improper data handling triggers compliance violations (GDPR, HIPAA, PCI-DSS) and substantial fines. Even a single exposed admin password or API token in a public repository or log file can compromise an entire application.
04Vulnerable & Fixed Patterns
Vulnerable pattern
import logging
import sqlite3
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def authenticate_user(username, password):
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
user = cursor.fetchone()
logger.debug(f"User login attempt: {username}, password: {password}")
if user and user[2] == password:
return {"status": "success", "user_id": user[0], "password": password}
return {"status": "failed"}
Why it's vulnerable: The password is logged in plain text and also returned in the response. Anyone with access to logs or network traffic can read the credential.
Fixed pattern
import logging
import sqlite3
import hashlib
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def authenticate_user(username, password):
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
user = cursor.fetchone()
logger.debug(f"User login attempt: {username}")
if user and hashlib.sha256(password.encode()).hexdigest() == user[2]:
return {"status": "success", "user_id": user[0]}
return {"status": "failed"}
Why it's vulnerable: The full card number and CVV are logged and transmitted in plain text. Error logs are often world-readable or backed up without encryption.
Identify sensitive data in your application: passwords, tokens, API keys, credit card numbers, SSNs, email addresses, session IDs. Document where each is used.
Never log sensitive data: if you must log for debugging, mask or hash it (e.g., log only the last 4 digits of a card number, or a hash of a password).
Remove sensitive data from error messages and responses: return only what the user needs; never echo back credentials or tokens.
Encrypt sensitive data at rest and in transit: use TLS/HTTPS for all network communication; encrypt database fields containing PII or credentials.
Secure your logs and backups: restrict file permissions, encrypt backup media, and regularly audit who can access logs and archived data.
Use environment variables or secure vaults for secrets: never hardcode API keys, database passwords, or tokens in source code or configuration files.
06Signs You May Already Be Affected
Check your application logs, error pages, and backup files for plain-text passwords, API keys, or personal information. Search your version control history (Git, etc.) for accidentally committed secrets using tools like git log -p or automated scanners. Review who has access to logs, temporary directories, and backups—if non-admin users or external systems can read them, sensitive data may be exposed.