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 datawasfalse— 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-suppliedisAdmin/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
zodandjoisupport 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
isAdminflag, acreatedAttimestamp)?" — 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.