Sensitive Data in Logs
Also Known As
logging secrets
PII in logs
credential logging
TL;DR
Logging passwords, tokens, credit card numbers, or PII — log aggregators store data indefinitely and are often less secured than primary databases.
Explanation
Application logs are collected by aggregators (ELK, Datadog, Splunk) where they are stored, indexed, and accessed by many more people than the primary database. Logging request parameters, exception messages containing credentials, or full user objects routinely exposes sensitive data. Structured logging makes this worse — a well-intentioned context object dumps everything. Always explicitly allowlist what gets logged rather than logging everything and filtering after.
Common Misconception
✗ Logs are only seen by developers so sensitive data is acceptable — log aggregators are accessed by devops, security, support teams, and third-party SIEM tools; treat logs as semi-public.
Why It Matters
A password logged in a debug message, then shipped to an external log aggregator, means that password is now stored in plaintext in a system with weaker access controls than the auth database.
Common Mistakes
- Logging entire request arrays: error_log(print_r($_POST, true)) — captures passwords and tokens.
- Logging exception messages that include SQL with bound parameters containing user data.
- Logging full user objects including hashed passwords and API keys.
- Not masking card numbers — only log last 4 digits: ****1234.
Code Examples
✗ Vulnerable
// Logs entire POST including passwords:
error_log('Request: ' . print_r($_POST, true));
// Logs exception with credentials in message:
try {
authenticate($user, $password);
} catch (Exception $e) {
$logger->error($e->getMessage()); // May contain password
$logger->debug('Context', ['user' => $user, 'pass' => $password]);
}
✓ Fixed
// Explicit allowlist — only log safe fields:
$logger->info('Login attempt', [
'user_id' => $user->id,
'ip' => $request->ip(),
'success' => $authenticated,
// No password, no token, no PII beyond user_id
]);
// Mask sensitive values:
$logger->debug('Payment', [
'card_last4' => substr($card, -4),
'amount' => $amount,
// Never: full card number, CVV, or auth token
]);
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
5 Apr 2026
Views
16
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 6
Perplexity 2
Google 2
Unknown AI 2
ChatGPT 2
Ahrefs 1
Also referenced
How they use it
crawler 13
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Medium
⚡ Quick Fix
Audit your log format and scrub PII before logging — add a Monolog processor that redacts known sensitive keys (password, token, card_number, ssn) from all log context arrays
📦 Applies To
PHP 7.0+
any
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Password or token in log context array; credit card number in exception message logged; PII in Sentry error report; email in query parameter logged in access log
Auto-detectable:
✓ Yes
semgrep
sentry-scrub
trufflehog
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Line
CWE-312
CWE-532