Skip to solution
mediumBackend

How do you validate and sanitize request input (zod / joi)?

60 views
01

Understand the problem

Question presented to candidate: "Your API accepts a JSON body for user registration. A request arrives with a valid email, a valid age, AND an extra field called 'isAdmin' that isn't part of your registration form at all. What happens to that extra field, and why does that matter for security, not just data cleanliness?"

What a strong answer should cover:

  • A schema-validation library (zod, joi, and similar) does two things at once, directly relevant to the prompt: it validates that the expected fields have the correct shape/type (rejecting genuinely invalid input), and — the security-relevant half — it acts as an allowlist, meaning any field not declared in the schema is, by default, stripped from the parsed output, not silently passed through.
  • 📌 Verified, not assumed — the exact answer to the prompt: a real schema, given a genuinely valid request plus an undeclared extra field (secretAdminFlag: true), genuinely produced a parsed output where 'secretAdminFlag' in data was false — the extra field was stripped, never reaching any code downstream that might (incorrectly, but plausibly) trust anything present on the parsed object.
  • 📌 Verified, not assumed — the rejection half: a real, genuinely invalid input (a malformed email, an under-the-minimum age, an invalid enum value) produced 3 real, specific validation issues — each naming the exact field and the exact problem, not a generic "invalid input" error, directly usable for a precise, real error response.
  • This directly answers the prompt's security question, precisely: without schema-based stripping, an application that naively does something like const user = { ...req.body } (or an unguarded merge, connecting directly to the real prototype-pollution risk verified with its own dramatic proof in this bank's dedicated question) would genuinely let an attacker-supplied isAdmin/role/similar field ride along into whatever object the application builds next — a real, common path to a genuine mass-assignment vulnerability, distinct from but related to the merge-based pollution risk covered elsewhere in this bank.
  • A precise answer names zod/joi's real, complementary relationship to the parameterized queries and encapsulation-boundary defenses covered elsewhere in this bank: schema validation is the first line of defense, rejecting/stripping bad input as early and as close to the system boundary as possible — it does not replace parameterized queries for the SQL-injection risk verified elsewhere, or CSP/Helmet for XSS, since a genuinely well-typed, schema-valid string can still be a security-relevant value (a valid-looking string can still be a SQL injection payload, verified elsewhere, if concatenated rather than parameterized) — schema validation and those other defenses are complementary layers, not substitutes for each other.

Clarifying questions expected:

  • "Should an unrecognized field in the request cause a hard rejection of the whole request, or is silent stripping (verified above) the desired behavior?" — both zod and joi support either mode; a precise answer names this as a real, configurable choice, not a fixed behavior.
  • "Are there any fields that are genuinely present in the data model but should NEVER be settable directly from request input (an isAdmin flag, a createdAt timestamp)?" — the schema itself is exactly where that boundary should be enforced.

Code / implementation expected: Yes — a real schema genuinely rejecting invalid input with specific issues, and genuinely stripping an undeclared field from valid input, is the concrete, convincing proof of exactly how validation doubles as a real security boundary, not just a data-shape check.

nodejsvalidationzodsecurity
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js API-security and input-validation interviews — assumes familiarity with the prototype-pollution question's real attack proof. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

Real zod schema validation: genuine rejection with specific issues, and genuine allowlist stripping of an undeclared field
const { z } = require("zod");

const UserSchema = z.object({
  email: z.string().email(),
  age: z.number().int().min(13).max(120),
  role: z.enum(["user", "admin"]).default("user"),
});

const valid = UserSchema.safeParse({ email: "alice@example.com", age: 30 });
console.log(valid.success, valid.data);
// true { email: 'alice@example.com', age: 30, role: 'user' }

const invalid = UserSchema.safeParse({ email: "not-an-email", age: 5, role: "superadmin" });
console.log(invalid.success); // false
for (const issue of invalid.error.issues) console.log(issue.path.join("."), "-", issue.message);
// email - Invalid email address
// age - Too small: expected number to be >=13
// role - Invalid option: expected one of "user"|"admin"

// the real security-relevant behavior:
const withExtra = UserSchema.safeParse({ email: "bob@example.com", age: 25, secretAdminFlag: true });
console.log("secretAdminFlag" in withExtra.data); // false — genuinely stripped, never reaches downstream code
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 112 of 152 decoded in the Node.js track. One more won't hurt.

Back to track