# Content-Type header validated

- **Pattern:** `ab-000384` (`api-security.input-validation.content-type-validation`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000384
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000384)

## Why it matters

Content-Type confusion attacks exploit the gap between what a server expects and what it receives. CWE-436 (Interpretation Conflict) captures the class: when a server parses a multipart form body as JSON, or an XML document through a JSON parser, unexpected behavior follows — from parser differentials enabling prototype pollution to content-sniffing attacks where the browser reinterprets a JSON response as HTML. OWASP API3 (Broken Object Property Level Authorization) and API6 both flag media type validation as a control boundary. APIs that accept arbitrary content types are vulnerable to parser-switching attacks where the attacker changes the Content-Type to trigger a different code path.

## Severity rationale

Medium because content-type confusion can redirect parsing to a different code path, creating exploitable differentials in applications that branch on content format.

## Remediation

Validate Content-Type on all mutating requests before parsing the body. Return 415 Unsupported Media Type for unexpected types — don't silently parse or coerce.

```ts
// src/middleware.ts (Next.js)
export function middleware(req: NextRequest) {
  const method = req.method
  if (['POST', 'PUT', 'PATCH'].includes(method)) {
    const ct = req.headers.get('content-type') ?? ''
    if (!ct.startsWith('application/json')) {
      return new Response(
        JSON.stringify({ error: 'Content-Type must be application/json' }),
        { status: 415, headers: { 'Content-Type': 'application/json' } }
      )
    }
  }
  return NextResponse.next()
}

export const config = { matcher: '/api/:path*' }
```

## Detection

- **ID:** `content-type-validation`
- **Severity:** `medium`
- **What to look for:** Enumerate every relevant item. Check middleware or route handlers for explicit Content-Type header validation. Verify that requests with unexpected content types are rejected or handled appropriately.
- **Pass criteria:** At least 1 of the following conditions is met. The API validates that incoming requests have the expected Content-Type header (e.g., application/json for JSON endpoints). Requests with incorrect Content-Type are rejected with a 415 Unsupported Media Type response.
- **Fail criteria:** The API does not check the Content-Type header, or invalid content types are accepted without validation.
- **Skip (N/A) when:** The API only handles GET requests or accepts all content types.
- **Detail on fail:** `"No Content-Type validation — requests with incorrect content types are accepted and processed"`
- **Remediation:** Add Content-Type validation middleware:

  ```ts
  const validateContentType = (req, res, next) => {
    if (req.method !== 'GET' && req.method !== 'HEAD') {
      const contentType = req.headers['content-type']
      if (!contentType || !contentType.includes('application/json')) {
        return res.status(415).json({ error: 'Content-Type must be application/json' })
      }
    }
    next()
  }

  app.use(validateContentType)
  ```

## External references

- cwe CWE-20
- cwe CWE-436
- owasp A03

Taxons: injection-and-input-trust

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