cybersecurity · intermediate · ~15 min · safe pentest lab

Object-level authorization: stop IDOR / BOLA

Enforce server-side object ownership and bounds-check an attacker-controlled index before use.

Challenge

Broken Object-Level Authorization (BOLA/IDOR) is the #1 API risk: an endpoint returns or edits an object using a caller-supplied id without checking the caller actually owns it. The defensive fix is an explicit ownership check on the server — and, in C, a bounds check before you index the ownership table.

Task

Implement int owns(const int *owner_of, int n_objects, int caller_id, int object_id).

owner_of[i] is the user id that owns object i. Return 1 only if object_id is a valid index (0 <= object_id < n_objects) and owner_of[object_id] == caller_id; otherwise return 0. Reject an out-of-range object_id before indexing the array — never read out of bounds.

Example

owns(t, 5, 10, 0)   -> 1     (object 0 owned by user 10)
owns(t, 5, 10, 2)   -> 0     (object 2 owned by someone else)
owns(t, 5, 10, 5)   -> 0     (out of range: reject, do not index)
owns(t, 5, 10, -1)  -> 0     (negative index: reject)

Edge cases

  • object_id == n_objects and any larger/negative value must return 0 (no out-of-bounds read).
  • Ownership must match exactly; deny by default.

Input format

An ownership table owner_of[n_objects], a caller_id, and a caller-supplied object_id.

Output format

1 if the caller owns a valid object_id, else 0.

Constraints

n_objects >= 0. object_id is attacker-controlled and may be any int.

Starter code

int owns(const int *owner_of, int n_objects, int caller_id, int object_id) {
    /* TODO: return 1 only when object_id is a valid index AND
       owner_of[object_id] == caller_id. Reject an out-of-range object_id
       (return 0) BEFORE indexing the array. */
    return -1;
}

Common mistakes

Indexing owner_of[object_id] before checking the bounds (out-of-bounds read); trusting the client's object_id; allowing access when ids merely 'look valid'.

Edge cases to handle

object_id out of [0, n_objects) (including == n_objects, negative, and far-out values) must return 0 without indexing the array.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.