Description
Sensitive data in logs occurs when applications write security-relevant information — passwords, session tokens, API keys, credit card numbers, health data, or personally identifiable information — into log files or centralised logging systems. CWE-532 — Insertion of Sensitive Information into Log File defines this class of vulnerability, which sits at an uncomfortable intersection of the logging practices required for debugging and the data protection requirements imposed by security and compliance frameworks.
Log data typically has a far wider audience than the application itself. Developers, operations engineers, security analysts, third-party monitoring vendors, and cloud provider support staff may all have read access to application logs. Retention periods often stretch to 90 days or more, meaning a token or password logged even briefly persists in multiple log storage systems long after it has been rotated.
Under A09:2021 — Security Logging and Monitoring Failures, the OWASP Top 10 highlights that this vulnerability class is about both inadequate logging (missing security events) and inappropriate logging (recording sensitive data). Excessive logging that captures secrets is just as problematic as insufficient logging that misses breaches.
How It Works
Request body logging — a common debugging pattern that logs entire HTTP request bodies:
import logging
logger = logging.getLogger(__name__)
def login(request):
logger.debug(f"Login request body: {request.body}")
# Logs: Login request body: {"username": "alice", "password": "MySecretP@ss!"}
Token logging in API clients — SDK initialisation or HTTP client wrappers that log request headers including Authorization:
axios.interceptors.request.use(config => {
console.log('Request headers:', config.headers);
// Logs: Request headers: { Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9...' }
return config;
});
Error handler credential leakage — exception messages that include database connection strings:
ERROR: Connection failed: mysql://admin:hunter2@prod-db:3306/appdb
at DBPool.connect (pool.js:88)
Mobile app analytics — crash reporting SDKs (Sentry, Crashlytics, Firebase Crashlytics) configured with overly broad data capture can include in-memory values — including session tokens — in crash reports sent to third-party servers.
Impact
- Session hijacking — session tokens or JWT values in logs allow anyone with log access to impersonate users without their credentials.
- Credential theft — plaintext passwords logged during authentication are usable across other services if users reuse passwords.
- Regulatory breach — logging PII (names, email addresses, health data) to insufficiently protected systems violates GDPR, HIPAA, and PCI-DSS, triggering notification and fine obligations.
- Insider threat surface — every engineer with read access to logs becomes a potential insider threat if those logs contain credentials or sensitive personal data.
- Third-party data exposure — crash reporting and APM tools that receive sensitive log data represent a supply chain risk — a breach of the monitoring vendor exposes production secrets.
Detection
- Search log stores for sensitive patterns — query your ELK or Splunk instance for patterns like
password,passwd,token,Bearer,Authorization,secret, credit card number patterns (\d{16}), and connection string prefixes (jdbc:,mongodb://). - Instrument a test authentication flow — perform a login with a known test credential and then search all log outputs (application logs, access logs, APM traces) for that exact credential string.
- Review logging configuration — audit log format strings and structured logging schemas in application code. Look for any place where
request.body,request.headers, or full exception objects are passed to log calls. - Inspect mobile crash reports — review a sample of Sentry or Crashlytics crash reports for the presence of authentication headers or session data in the breadcrumb trail or local variables.
- Check cloud provider logs — review AWS CloudTrail, GCP Audit Logs, or Azure Monitor for any secrets appearing in API call parameters logged by the cloud platform itself.
Remediation
Implement log scrubbing middleware. Intercept log writes and redact known-sensitive field names before they are recorded. Libraries like loguru (Python), logback (Java), and custom Express.js middleware can filter or mask fields.
Use structured logging with explicit field selection. Log discrete fields rather than serialising entire request or response objects. This makes it impossible to accidentally log a field that was not explicitly included.
# Bad: logs everything
logger.info(f"User logged in: {user.__dict__}")
# Good: explicit fields only
logger.info("User logged in", extra={"user_id": user.id, "ip": request.remote_addr})
Configure crash reporting SDKs carefully. Disable automatic capture of HTTP request headers and body data in Sentry, Crashlytics, and similar tools. Use beforeSend hooks to scrub events before transmission.
