In short
Every field in a request body is a stranger's opinion. Validate it at the door, and the rest of your code gets to work with clean, predictable data.
Rejecting or cleaning malformed, unexpected, or malicious input before it reaches your business logic or database — the single most effective general-purpose security practice.

Think of it like this
The station luggage scanner
At a big railway station, every bag rolls through the scanner before it reaches the platform. Most are fine. The odd one with something dangerous is pulled out right there, not on the train. Validation is that scanner for your API.
Watch it happen
A signup request through the checks
1/5The body arrives: { "email": " Riya@Mail.com ", "age": "19", "role": "admin" }.
The big ideas
What you need to know
Validate on the server
Frontend checks are for user comfort. Attackers skip your form and send raw requests, so the server must check again.
Allowlist, not blocklist
Describe what good input looks like: type, length, format. Reject everything else instead of chasing bad patterns.
Sanitise means clean up
Trim spaces, normalise case, strip unknown fields and unsafe HTML. It makes data consistent, not magically safe.
One schema, many uses
A Zod schema gives runtime checks and TypeScript types together, so your types can't drift from your checks.
See it in code
Walk through the code
1import { z } from "zod";2 3const SignupSchema = z.object({4 email: z.email(),5 age: z.number().int().min(16).max(100),6 name: z.string().trim().min(1).max(50),7});8 9app.post("/signup", (req, res) => {10 const result = SignupSchema.safeParse(req.body);11 if (!result.success) return res.status(400).json(result.error.issues);12 createUser(result.data); // only clean, typed data gets here13 res.status(201).end();14});1/3The schema describes good input: a real email, a whole-number age in range, and a trimmed name of sane length.
z.object strips keys you didn't declare, so a sneaky "role": "admin" never reaches createUser. That alone blocks a whole class of mass-assignment bugs.
Save yourself the pain
Common mistakes
Oops
Passing req.body straight into db.user.create().
Do this instead
Pick fields through a schema first. Otherwise a user can set isAdmin or balance just by adding it to the JSON.
Oops
Trusting that the React form already validated it.
Do this instead
Run the same rules on the server. Share the Zod schema between both if you like.
Your mission
Put a scanner on one endpoint
Quick check
Why is z.object useful against mass-assignment attacks?
Go deeper
- 1Add strict validation (type, length, format) to every field of a public endpoint.
- 2Reject unexpected extra fields in a request body rather than silently ignoring them.
- 3Validate on the server even if the client also validates — never trust the client.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.