Heimdall
Heimdall ScanOpen Beta
CriticalProAPI Hardening

Unvalidated API input on write routes

Every API route that accepts data needs to know exactly what shape that data should take, and reject anything that does not match. Without that check, attackers can send extra fields, wrong types, or oversized payloads that the route was never designed to handle.

#What goes wrong

A typical AI-generated route looks like: const { name, email } = await req.json(). Whatever the client sends gets used. An attacker can send { name: '…', email: '…', isAdmin: true } and if the handler passes that object straight into a database insert with spread syntax, congratulations, they just made themselves an admin.

#Why it matters

Mass assignment, prototype pollution, and SQL injection through type confusion all start with a missing validation step. Beyond security, unvalidated inputs cause runtime errors that crash production. The first 500 you ship is almost always a missing validation check on a real user's weird input.

#How Heimdall checks for this

Heimdall reads every POST, PUT, PATCH, and DELETE route and looks for any usage of req.json() or req.body that is not wrapped in a schema parse from Zod, Yup, or Joi. The AI step distinguishes real validation from cosmetic checks like a single typeof comparison.

#How to fix it

Define a Zod schema describing exactly the fields the route accepts, parse the body with safeParse, and return 400 with the validation errors if the parse fails. Never spread the parsed object directly into a database write. Pick the fields you actually want by name.

Frequently asked questions

Is TypeScript enough?

Which library should I pick?

Do GET routes need validation too?

Run this check on your own repo

Heimdall scans your GitHub repo for this and 16 other issues in under a minute.