Calling OrderSchema.parse(body) after prisma.order.create({ data: body }) already ran is not validation — it's an audit log that arrives after the crime. The bad data is committed to the database whether the parse throws or not. CWE-696 (Incorrect Behavior Order) captures this: the side effect precedes the safety check. An attacker who sends a malformed payload wins regardless of the parse result, because the DB write already succeeded.
High because validating after the write means every mutation executes with unvalidated input — the check fires after the attack surface is already exploited.
Move the parse call to the first statement after req.json(). Validation must throw before any prisma.* call is reachable.
// Bad: write happens before validation
export async function POST(req: Request) {
const body = await req.json()
const order = await prisma.order.create({ data: body }) // unvalidated write
OrderSchema.parse(body) // too late — commit already happened
return Response.json(order)
}
// Good: validate first, then write
export async function POST(req: Request) {
const body = await req.json()
const data = OrderSchema.parse(body) // throws before any DB interaction
const order = await prisma.order.create({ data })
return Response.json(order)
}
ID: ai-slop-security-theater.unenforced-validation.validation-runs-before-db-write
Severity: high
What to look for: For mutating handlers that DO have a validation invocation, before evaluating, extract and quote the validation call line and the database write line. Verify the validation call appears BEFORE the database write in the function body's execution order. Count all handlers where validation exists but happens AFTER the write OR validation only validates a subset of the body that doesn't overlap with what's written.
Pass criteria: 100% of mutating handlers with validation perform validation BEFORE the database write. Report: "X handlers with validation, Y validate-before-write, 0 validate-after-write."
Fail criteria: At least 1 handler validates input AFTER writing to the database.
Skip (N/A) when: Project has 0 mutating handlers OR no mutating handler invokes validation.
Detail on fail: "1 handler validates after DB write: app/api/orders/route.ts POST writes to prisma.order.create then calls OrderSchema.parse(body) — the write happens with unvalidated data"
Remediation: Validation after the write is meaningless — the bad data is already in the database. Reorder the calls:
// Bad: write happens before validation
export async function POST(req: Request) {
const body = await req.json()
const order = await prisma.order.create({ data: body }) // unvalidated
OrderSchema.parse(body) // too late
return Response.json(order)
}
// Good: validate first
export async function POST(req: Request) {
const body = await req.json()
const data = OrderSchema.parse(body) // throws before DB write
const order = await prisma.order.create({ data })
return Response.json(order)
}