cybersecurity · intermediate · ~15 min · safe pentest lab
Enforce function-level authorization server-side with an explicit deny-by-default allowlist, and safely reject NULL/empty/unknown attacker-controlled input before acting on it.
Broken Function Level Authorization (BFLA) happens when an API decides who you are but forgets to check whether your role is allowed to perform this specific action. A low-privileged user (role 1) who can only read sends a crafted request asking to delete, and a fail-open endpoint happily performs it because it never consulted an authorization policy.
The protected asset here is a fixed permission policy baked into the grading harness. Your job is to be the server-side authorization gate. Implement action_allowed(role, action) so it consults a fixed allowlist and returns 1 only when that exact role is granted that exact action, and 0 otherwise.
The policy the harness enforces:
readread, writeread, write, deleteDeny by default. Any unknown role, any action not granted to that role, and any invalid input (a NULL or empty action string) must return 0. Do not dereference the action pointer before checking it for NULL, and do exact string matching only (READ is not read).
action_allowed(1, "read") -> 1action_allowed(1, "delete") -> 0action_allowed(3, "delete") -> 1action_allowed(9, "read") -> 0Two arguments: int role (an integer role id; only 1, 2, 3 are known roles) and const char *action (a NUL-terminated string naming the requested action, e.g. "read", "write", "delete"; may be NULL or empty).
Return int 1 if the given role is explicitly granted the given action by the fixed allowlist, otherwise return 0.
C11. No dynamic allocation, no I/O, no global mutable state. The action pointer may be NULL or point to an empty string and must be handled safely before any dereference. Matching is exact and case-sensitive. Deny by default: anything not explicitly on the allowlist returns 0.
int action_allowed(int role, const char *action){
/* TODO: consult a FIXED allowlist and return 1 only when this exact
role is granted this exact action; return 0 for everything else
(unknown role, ungranted action, NULL/empty action).
This stub fails open and is INSECURE — replace it. */
(void)role; (void)action;
return -1;
}
Failing open (returning 1 by default and only denying a few known-bad cases) instead of denying by default; dereferencing action with strcmp before checking it for NULL, causing a crash; using strncmp/prefix or case-insensitive matching that lets "read_all" or "READ" slip through; checking only the action and ignoring the role, so any role can do anything (the exact BFLA flaw); assuming a higher role's permissions imply a lower role is fine.
action is NULL; action is the empty string ""; unknown action for an otherwise valid role (e.g. role 3 asking to "drop"); action valid for a higher role but not this one (role 1 asking to "delete"); unknown role id (9); negative role (-1); role 0; case-variant action ("READ") that must not match "read".
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.