# Critical handlers are not empty or return-only

- **Pattern:** `ab-000266` (`ai-slop-half-finished.incomplete-impl.empty-critical-handlers`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000266
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000266)

## Why it matters

An empty `/api/auth/login` handler returns success without verifying credentials, so any request authenticates anyone. An empty `/api/webhooks/stripe` handler 200s and drops the event, so Stripe stops retrying and payments never reconcile. These stubs map directly to OWASP A07 (Identification & Authentication Failures) and to silent revenue loss. AI scaffolds these endpoints early to keep routes compiling; the implementation gets deferred and forgotten.

## Severity rationale

High because empty auth and webhook handlers bypass identity checks and silently drop critical business events.

## Remediation

Implement the actual logic for every auth, payment, and webhook handler before merging. Verify credentials, validate signatures, persist state, and emit structured errors on failure. Example for `app/api/auth/login/route.ts`:

```ts
export async function POST(req: Request) {
  const { email, password } = await req.json()
  const user = await verifyCredentials(email, password)
  if (!user) return Response.json({ error: 'Invalid credentials' }, { status: 401 })
  const session = await createSession(user.id)
  return Response.json({ session })
}
```

## Detection

- **ID:** `empty-critical-handlers`
- **Severity:** `high`
- **What to look for:** Walk critical handler files (API handlers under paths containing `auth`, `login`, `signup`, `signin`, `logout`, `signout`, `reset-password`, `forgot-password`, `verify`, `session`, `checkout`, `payment`, `billing`, `subscribe`, `webhook`). For each exported HTTP method handler, count the number of meaningful statements in its body (excluding comments, `use server` directives, and whitespace). A handler is "empty" if its body contains 0 or 1 meaningful statements (just a return). Count all critical handlers with empty or near-empty bodies.
- **Pass criteria:** 0 critical handlers have empty or near-empty bodies. Report: "Scanned X critical handlers (auth, payment, etc.), 0 are empty."
- **Fail criteria:** At least 1 critical handler has an empty body or only a single return statement.
- **Skip (N/A) when:** Project has 0 critical handler files (no auth, payment, or webhook routes detected).
- **Detail on fail:** `"2 empty critical handlers: app/api/auth/login/route.ts POST handler body is '{ return Response.json({ ok: true }) }', app/api/webhooks/stripe/route.ts POST handler is '{}'"`
- **Remediation:** An empty auth handler returns success without authenticating. An empty webhook handler silently drops events. These are worse than missing endpoints because clients think the operation succeeded. Implement each critical handler:

  ```ts
  // Bad: empty auth handler
  export async function POST() {
    return Response.json({ ok: true })
  }

  // Good: actual auth logic
  export async function POST(req: Request) {
    const { email, password } = await req.json()
    const user = await verifyCredentials(email, password)
    if (!user) {
      return Response.json({ error: 'Invalid credentials' }, { status: 401 })
    }
    const session = await createSession(user.id)
    return Response.json({ session })
  }
  ```

## External references

- owasp A07

Taxons: placeholder-hygiene

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