---
title: Do Not Log Credentials Or Tokens
impact: MEDIUM
impactDescription: prevents credential exposure in logs
tags: logging, credentials, tokens, secrets, security, php
---

## Do Not Log Credentials Or Tokens

Logs are frequently stored in plaintext and accessible by many developers or automated tools. Including sensitive credentials (passwords, API tokens, session IDs) in logs can lead to account takeovers if the logs are ever compromised or accidentally exposed.

**Incorrect (logging sensitive data):**

```php
// Logging user credentials
Log::info('Login attempt', [
    'username' => $request->username,
    'password' => $request->password // NEVER!
]);

// Logging all request headers
Log::debug('Request headers', $request->headers->all());
// Authorization header contains Bearer tokens!

// Logging full request body
Log::info('Incoming form data', $request->all());
// May contain password, credit_card, or secret_key
```

**Correct (sanitized logging):**

```php
// 1. Omit sensitive fields explicitly
Log::info('Login attempt', [
    'username' => $request->username,
    // password excluded
]);

// 2. Redact sensitive headers
$headers = $request->headers->all();
if (isset($headers['authorization'])) {
    $headers['authorization'] = '[REDACTED]';
}
Log::debug('Request headers', $headers);

// 3. Use an allowlist or a masking helper
function sanitizeForLog(array $data): array {
    $sensitive = ['password', 'token', 'secret', 'credit_card', 'api_key'];
    foreach ($sensitive as $field) {
        if (isset($data[$field])) {
            $data[$field] = '[REDACTED]';
        }
    }
    return $data;
}

Log::info('Request data', sanitizeForLog($request->all()));
```

**Never log:**
- Passwords (plaintext or hashes)
- API keys, JWT tokens, OAuth tokens
- Credit card numbers, CVVs
- Session IDs (`PHPSESSID`)
- Personal Identifiable Information (PII) like SSNs where not required

**Tools:** Monolog (custom formatters), PHPStan, SonarQube, Log analysis tools
