cybersecurity · beginner · ~15 min · safe pentest lab
Understand mass-assignment (auto-binding) attacks and implement a deny-by-default input allowlist that rejects protected fields, unknown fields, and malformed input (NULL/empty) using exact matching.
Many web frameworks let a client submit a JSON body and then blindly copy every key/value pair onto a server-side object: user.name = body.name, user.role = body.role, and so on. The insecure assumption is that clients only send the fields the form shows. An attacker who adds an unexpected key like is_admin, role, or balance to the request can silently escalate privileges or edit protected state. This is mass assignment, and the standard defense is an input allowlist: only fields you explicitly permit may ever be written.
The asset is a user profile record. The threat is an attacker adding extra JSON keys to overwrite protected columns. Your guard is the last line that decides which incoming field names are writable.
Implement is_allowed_field(const char *field). Return 1 only when field exactly matches one of the four permitted input fields: name, email, bio, avatar_url. For anything else — protected fields, unknown fields, or malformed input — return 0. This is a fixed, in-memory allowlist; you never touch a network or filesystem.
NULL pointer => 0 (never dereference it)."" => 0."Name"), prefixes ("nam"), superstrings ("name_admin"), and trailing whitespace ("email ") are NOT matches => 0.Deny by default: if you are not certain a field is on the allowlist, reject it.
Given the allowlist {name, email, bio, avatar_url}:
is_allowed_field("email") -> 1
is_allowed_field("is_admin") -> 0
is_allowed_field(NULL) -> 0
A single C string field (may be NULL) representing an incoming JSON field name the client wants to write.
Return int 1 if field is exactly one of the four allowed input fields, otherwise 0.
C11. No dynamic allocation required. Must not dereference a NULL pointer. The allowlist is fixed: name, email, bio, avatar_url. Matching is exact and case-sensitive. The harness provides all standard includes (stdio.h, string.h, stdlib.h, stdint.h).
int is_allowed_field(const char *field){
/* TODO: return 1 only if field is EXACTLY one of the allowed input
fields (name, email, bio, avatar_url); otherwise return 0.
Remember: handle NULL and empty string, and use EXACT matching so
attacker keys like is_admin / role / balance are rejected.
This insecure stub allows everything -- replace it. */
(void)field;
return 1;
}Using strncmp with a short length so 'name_admin' or 'name123' passes; forgetting the NULL check and crashing; doing a case-insensitive compare so 'Name' or 'ROLE' behaves unexpectedly; using a denylist (blocking only is_admin/role) instead of an allowlist, which fails open on any protected field you forgot to list; treating empty string as allowed.
NULL pointer returns 0 without dereferencing; empty string returns 0; case-different variants like 'Name' return 0; prefixes like 'nam' return 0; superstrings like 'name_admin' return 0; trailing/leading whitespace like 'email ' returns 0; protected fields is_admin/role/balance return 0.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.