# Custom 404 and 500 error pages are configured

- **Pattern:** `ab-000015` (`security-headers.info-exposure.custom-error-pages`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000015
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000015)

## Why it matters

Default framework error pages expose the framework name, version, and sometimes a stack trace to anyone who triggers a 404 or 500. Beyond information leakage, an app with no custom error pages signals to users (and attackers) that error cases were never designed — raising the question of what else was left to defaults. CWE-209 (Error Message With Sensitive Information) and CWE-756 (Missing Custom Error Page) both apply. OWASP A05 (Security Misconfiguration) identifies default error pages as a configuration gap. Custom error pages also prevent operational confusion: a customer who hits a raw framework 500 page is far more likely to churn than one who sees a branded, helpful message.

## Severity rationale

Low because default error pages primarily enable passive information gathering — the concrete risk depends on what the framework exposes in its defaults.

## Remediation

Create both `app/not-found.tsx` and `app/error.tsx` in your Next.js app. The error page must be a client component; the not-found page can be a server component.

```tsx
// app/not-found.tsx
export default function NotFound() {
  return (
    <main>
      <h1>Page Not Found</h1>
      <p>The page you're looking for doesn't exist.</p>
    </main>
  )
}
```

```tsx
// app/error.tsx
'use client'
export default function Error({ reset }: { reset: () => void }) {
  return (
    <main>
      <h1>Something went wrong</h1>
      <button onClick={reset}>Try again</button>
    </main>
  )
}
```

Neither page should expose the caught error object, stack trace, or raw framework output in its markup.

## Detection

- **ID:** `custom-error-pages`
- **Severity:** `low`
- **What to look for:** Count all custom error pages present. At least 2 custom error pages are required: `app/not-found.tsx` or `pages/404.tsx` for 404 errors, and `app/error.tsx` or `app/global-error.tsx` for 500 errors. For other frameworks, check the equivalent error page customization.
- **Before evaluating:** Quote the file path and the exported component name (or first heading text) for each custom error page found. Example: "Found `app/not-found.tsx` exporting `NotFound` component with heading 'Page Not Found'."
- **Pass criteria:** Custom error pages exist for both 404 (e.g., `app/not-found.tsx` or `pages/404.tsx`) and 500 (e.g., `app/error.tsx` or `app/global-error.tsx`). Each page must render user-friendly content and not expose internal framework details, stack traces, or raw error objects in its markup.
- **Fail criteria:** No custom error pages found — the project relies on framework default error pages. Or only one of the two (404/500) is customized.
- **Skip (N/A) when:** Never.
- **Cross-reference:** For user-facing error handling patterns and error recovery UX, the Error Resilience audit covers error boundaries, retry logic, and graceful degradation.
- **Detail on fail:** `"No custom not-found.tsx or 404.tsx page — using framework default which may reveal internal details"` or `"Custom 404 exists but no custom 500/error page configured"`
- **Remediation:** Default error pages may reveal framework information or look unprofessional. Create custom error pages:

  ```tsx
  // app/not-found.tsx
  export default function NotFound() {
    return (
      <main>
        <h1>Page Not Found</h1>
        <p>The page you're looking for doesn't exist.</p>
      </main>
    )
  }
  ```

  ```tsx
  // app/error.tsx
  'use client'
  export default function Error() {
    return (
      <main>
        <h1>Something went wrong</h1>
        <p>We're working on it. Please try again later.</p>
      </main>
    )
  }
  ```

## External references

- cwe CWE-209
- cwe CWE-756
- owasp A05

Taxons: error-resilience, user-experience

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