cybersecurity · intermediate · ~15 min · safe pentest lab
Enforce server-side function-level authorization with a deny-by-default rank check, validating both the caller's role and the required role before comparing them, so that invalid or forged privilege values are rejected.
An API exposes privileged actions (delete users, change billing, promote accounts). Each action declares a required role. The insecure assumption developers make is that hiding a button or checking the role only on the client is enough — but an attacker calls the endpoint directly and the server must decide, on its own, whether the caller is allowed.
Roles are ranked 0..4: guest(0), user(1), mod(2), admin(3), superadmin(4). Your gatekeeper receives the caller's user_role and the endpoint's required_role and must return 1 only when access is granted.
Task: Implement authorize_function. Return 1 iff both user_role and required_role are valid ranks in 0..4 AND user_role >= required_role. Otherwise return 0.
The asset: privileged API functions. The threat: a low-rank (or forged) caller invoking a high-rank action. Deny by default — any out-of-range, negative, or oversized role value must be rejected, never trusted or compared as-is. A forged role like 99 must not be treated as "higher than admin".
user_role == required_role) is allowed.0 and 4 are valid.>4 values on either argument mean deny.authorize_function(3, 2) -> 1 (admin may use a mod endpoint)authorize_function(1, 3) -> 0 (user denied an admin endpoint)authorize_function(99, 0) -> 0 (forged role rejected)Two ints: user_role (the caller's rank) and required_role (the rank the endpoint demands). Valid ranks are 0..4; any other value is attacker-controlled/invalid input.
Return int 1 if access is granted, 0 if denied.
Valid roles are integers 0..4 inclusive. Either argument may be any int (including negative or large values) and must be validated before use. No I/O, allocation, or global state — pure decision function.
int authorize_function(int user_role, int required_role){
/* TODO: enforce deny-by-default rank authorization.
- reject any role outside 0..4 (negative, or > 4)
- grant only when user_role >= required_role
Replace this insecure stub. */
(void)user_role; (void)required_role;
return -1; /* insecure placeholder: fails the tests */
}Comparing user_role >= required_role without first bounds-checking either value, so a forged role like 99 passes as super-admin; validating only user_role but not required_role; using > instead of >= and wrongly denying exact matches; treating negative numbers as valid low ranks; returning the boolean of the comparison before rejecting out-of-range inputs (fail-open instead of deny-by-default).
Exact-rank match (user_role == required_role) is allowed; lowest rank 0 and highest rank 4 are both valid; negative user_role or required_role is denied; a role above 4 (e.g. a forged 99) is denied and must NOT be read as outranking admin; if the required_role itself is out of range the request is denied even for a superadmin caller; both-invalid inputs are denied without any numeric comparison.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.