# Error logs scrubbed of sensitive data

- **Pattern:** `ab-001294` (`error-resilience.graceful-degradation-shutdown.scrub-sensitive-logs`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001294
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001294)

## Why it matters

Error logs that contain email addresses, passwords, API keys, or session tokens become a secondary attack surface. CWE-209 (information exposure through error messages) and OWASP A09 (security logging and monitoring failures) both cover this failure mode. NIST SP 800-53 AU-3 requires audit records to contain the right information — but not uncontrolled PII or credentials. A compromised logging pipeline or accidental log export can expose the credentials of every user whose request happened to error during a specific window.

## Severity rationale

Info severity because exploitation requires log access, which typically requires a separate compromise — but when that compromise occurs, unredacted logs amplify every credential in them.

## Remediation

Configure a `beforeSend` hook in your error tracking service to strip PII and secrets before they leave the process. Apply the same sanitization to your structured logger.

```ts
// lib/sentry.ts
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  beforeSend(event) {
    if (event.request?.data) {
      const data = event.request.data as Record<string, unknown>
      delete data.password
      delete data.token
      delete data.authorization
    }
    return event
  },
})
```

For your logger, sanitize at the call site with a helper: `logger.info({ user: omit(user, ['passwordHash', 'mfaSecret']) }, 'User action')`. Never log raw request bodies without stripping credential fields first.

## Detection

- **ID:** `scrub-sensitive-logs`
- **Severity:** `info`
- **What to look for:** Before evaluating, extract and quote the first 3 logging statements found in the codebase to check for sensitive data. Count all logging calls that could include user data, tokens, or passwords. Enumerate which sanitize sensitive fields. Check whether error logs contain sensitive data: PII (emails, phone numbers, SSNs), API keys, tokens, passwords. Look for before-send hooks in error tracking service configuration.
- **Pass criteria:** Error logs are scrubbed of sensitive data. If using an error tracking service, before-send hooks are configured to remove PII, API keys, and tokens. 100% of logging must exclude passwords, tokens, API keys, and PII.
- **Fail criteria:** Sensitive data found in error logs or error tracking service; no scrubbing configured.
- **Skip (N/A) when:** The application logs no sensitive data (unlikely but possible for simple apps).

- **Cross-reference:** For structured logging format, see `structured-logging`.
- **Detail on fail:** `"Email addresses and phone numbers appear in error stack traces"` or `"API keys visible in error logs sent to Sentry"`
- **Remediation:** Configure before-send hooks:

  ```ts
  // lib/logger.ts — sanitize sensitive data
  function sanitize(obj: any) { const clone = {...obj}; delete clone.password; delete clone.token; return clone }
  logger.info({ user: sanitize(userData) }, 'User action')
  ```

  ```ts
  // With Sentry
  Sentry.init({
    dsn: process.env.SENTRY_DSN,
    beforeSend(event) {
      // Remove user data from error message
      if (event.message) {
        event.message = event.message
          .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[email]')
          .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '[ssn]')
      }
      // Remove tokens from breadcrumbs
      if (event.breadcrumbs) {
        event.breadcrumbs = event.breadcrumbs.map(crumb => {
          if (crumb.data?.Authorization) {
            crumb.data.Authorization = '[redacted]'
          }
          return crumb
        })
      }
      return event
    }
  })
  ```

## External references

- cwe CWE-209
- owasp A09
- nist AU-3

Taxons: observability, cryptography-and-secrets

HTML version: https://auditbuffet.com/patterns/ab-001294
