# No unnecessary data in responses (over-fetching)

- **Pattern:** `ab-002200` (`saas-api-design.request-response.no-over-fetching`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002200
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002200)

## Why it matters

Returning `passwordHash`, internal tokens, or entire database rows in API responses is a direct CWE-200 (exposure of sensitive information) finding and maps to OWASP A01:2021 (broken access control) when those fields reveal authorization state. A single mistakenly-included `passwordHash` field in a user endpoint hands an attacker every credential they need to mount offline dictionary attacks. Over-fetching also inflates response payloads and tightly couples clients to database schema, making schema changes more expensive (ISO-25010:2011 functional-suitability.functional-correctness).

## Severity rationale

Low severity in aggregate because exploitation requires accessing the endpoint first, but any single sensitive-field leak (passwordHash, internalToken) is independently critical.

## Remediation

Create a serializer at `src/lib/serializers.ts` that explicitly allowlists fields before returning database records. Never spread a database row directly into a response:

```ts
// src/lib/serializers.ts
export function serializeUser(user: User) {
  const { id, name, email, createdAt, role } = user
  return { id, name, email, createdAt, role }
  // passwordHash, internalFlags, stripeCustomerId are never included
}
```

In Prisma, add explicit `select` clauses to queries rather than fetching and stripping fields after the fact — this prevents the data from ever crossing the DB boundary:

```ts
db.user.findUnique({ where: { id }, select: { id: true, name: true, email: true } })
```

## Detection

- **ID:** `no-over-fetching`
- **Severity:** `low`
- **What to look for:** Enumerate all route handlers and for each list the fields returned in responses. Look for: (1) password hashes, internal tokens, or other sensitive fields returned alongside user data; (2) entire database rows returned when only a subset of fields is needed; (3) deeply nested related data included by default when not always needed (e.g., every user response includes their full order history). Check ORM queries for `select *`-equivalent patterns, and check response serialization for field allowlisting.
- **Pass criteria:** At least 100% of route handlers return only the fields needed for the endpoint's purpose. Sensitive fields (password, passwordHash, internalId, secret, token, hash) are explicitly excluded from responses. Response shapes are clearly scoped.
- **Fail criteria:** Sensitive fields (password hashes, internal tokens, internal flags) are included in API responses; or large nested relationships are always returned even when not needed; or entire database rows are returned with no field selection.
- **Skip (N/A) when:** The project has no database queries or all API responses are simple key/value structures with no sensitive fields. Signal: no ORM or database dependency detected, or all routes return only fields constructed manually without database row spreading.
- **Detail on fail:** Example: `User endpoint returns passwordHash`. Identify the specific over-fetching issue (e.g., "User endpoint returns passwordHash and internalFlags fields; /api/orders includes full customer object on every item"). Max 500 chars.
- **Remediation:** Explicitly select only the fields you need in database queries. Create a serializer in `src/lib/serializers.ts` and explicitly exclude sensitive fields in responses. In Prisma: use `select: { id: true, name: true, email: true }` rather than returning the whole record. In raw SQL: name columns explicitly. Create a serializer or DTO (Data Transfer Object) function that converts database records to API-safe response shapes — this is a single place to audit what you're exposing. Never return a database row directly without going through a field allowlist.

## External references

- cwe CWE-200
- owasp A01
- iso-25010 functional-suitability.functional-correctness

Taxons: data-integrity

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