Missing Input Validation on API Route
A POST or PATCH API route spreads the raw request body into a database write without validating that fields exist, match expected types, or lie within expected ranges.
Typical error
Request body accepted without schema check
What this is
A generated API route that looks like:
export async function POST(req: Request) {
const body = await req.json()
const user = await db.user.create({ data: body })
return Response.json(user)
}Nothing stops the caller from including extra fields like isAdmin: true, role: 'owner', or credits: 999999. The database happily writes them.
Why AI tools ship this
"Spread the body" is the shortest code path that makes the endpoint work on the happy path. Validation is extra work the AI skips by default.
How to detect
Look for req.json() or await request.body being passed directly to db.*.create, db.*.update, or similar without any validation in between.
How to fix
Use Zod (or valibot) to define a schema for every API endpoint. Accept only what you declared.
import { z } from 'zod'
const CreateUserInput = z.object({
email: z.string().email(),
displayName: z.string().min(1).max(100),
})
export async function POST(req: Request) {
const result = CreateUserInput.safeParse(await req.json())
if (!result.success) {
return new Response(
JSON.stringify({ error: result.error.flatten() }),
{ status: 400 }
)
}
const user = await db.user.create({
data: {
email: result.data.email,
displayName: result.data.displayName,
// explicit fields only, no spread
},
})
return Response.json(user)
}Never pattern data: { ...body }. Always name every column you are writing.
Related
- Glossary: auth bypass
- Blog: Error handling in AI-built apps