# Production error responses do not expose stack traces

- **Pattern:** `ab-000013` (`security-headers.info-exposure.no-stack-traces`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000013
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000013)

## Why it matters

Stack traces returned to API clients expose the internal file system paths, dependency names and versions, function call chains, and sometimes SQL queries that make up your application's internals. Attackers use this reconnaissance to identify vulnerable libraries, understand data model structure, and craft targeted exploits. CWE-209 (Generation of Error Message Containing Sensitive Information) and CWE-200 (Exposure of Sensitive Information) directly describe this class of leak. OWASP A04 (Insecure Design) and A09 (Security Logging and Monitoring Failures) both apply. AI-generated codebases are particularly prone to this: the default catch-and-return-error pattern is the path of least resistance when the model is filling in error handling.

## Severity rationale

Critical because exposed stack traces provide attackers with dependency versions, file paths, and SQL structure — directly enabling targeted exploitation of known CVEs.

## Remediation

Wrap every API route in a catch block that logs the full error internally but returns a generic message to the client. Never return `err.message`, `err.stack`, or the error object directly.

```ts
// src/app/api/example/route.ts
try {
  // ... your logic
} catch (error) {
  console.error('[API error]', error) // internal log — full detail
  return Response.json(
    { error: 'Internal Server Error' },
    { status: 500 }
  )
}
```

For Next.js pages, create `app/error.tsx` and `app/global-error.tsx` that render user-friendly messages without exposing the caught error. Use an error tracking service (Sentry, Datadog) to capture full traces server-side — then you get observability without client exposure.

## Detection

- **ID:** `no-stack-traces`
- **Severity:** `critical`
- **What to look for:** Count all error handling locations: API route catch blocks, page error boundaries, and global error middleware. For each, check whether the full error object or stack trace is returned to the client. Check for `NODE_ENV` or environment-conditional error detail. In Next.js, check `app/error.tsx`, `app/global-error.tsx`, API route error handlers, and any global error middleware.
- **Pass criteria:** No more than 0 error handlers expose stack traces or internal details to clients. Error responses return generic messages (e.g., "Internal Server Error", "Something went wrong") without stack traces, file paths, dependency names, SQL queries, or internal details. Error handling is either unconditionally safe (always returns generic messages) or environment-conditional (shows details only when `NODE_ENV === 'development'` or equivalent).
- **Fail criteria:** Any API route or error handler returns full error objects, stack traces, or internal file paths to the client without environment checks.
- **Skip (N/A) when:** Never — every project should handle errors safely.
- **Detail on fail:** `"API route /api/users catches errors but returns err.message and err.stack directly in JSON response"` or `"No error boundary configured — framework default may expose stack traces in production"`
- **Remediation:** Stack traces expose internal file paths, dependency versions, and logic that attackers can use. Return generic errors to clients:

  ```ts
  // API route error handling
  try {
    // ... logic
  } catch (error) {
    console.error(error) // Log internally
    return Response.json(
      { error: 'Internal Server Error' },
      { status: 500 }
    )
  }
  ```

  For page errors, create a custom error boundary (`app/error.tsx`) that shows a user-friendly message.

## External references

- cwe CWE-209
- cwe CWE-497
- cwe CWE-200
- owasp A04
- owasp A09

Taxons: observability, error-resilience

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