00:00

#0505

Permission Check Bypass

Hard+200 XPA08:2021 Software and Data Integrity FailuresCWE-1321
Prototype PollutionAuthorization

Scenario

Your RBAC middleware does `policies[user.role][action]` to decide whether a request is allowed.

If an attacker sets their role to `__proto__`, the lookup walks up the prototype chain instead of checking a real policy entry — potentially returning `undefined` or a truthy prototype-inherited value and bypassing the permission check entirely.

Authorization checks are the last line of defence. A single prototype-traversal bug can hand every endpoint to an attacker without any credentials.

Your Tasks

  1. Validate that `user.role` is a direct own property of `policies` using `Object.prototype.hasOwnProperty.call`.
  2. Throw `'Invalid role'` if the role is not a recognised own property (including `__proto__`, `constructor`, or unknown strings).
  3. Throw `'Permission denied'` if the action is not allowed for a valid role.
  4. Return `true` when the action is explicitly allowed.

Examples

Example 1Exploit — role set to __proto__

checkPermission({role:'__proto__'}, 'read', policies)
// throws: 'Invalid role'

Example 2Safe — valid role with allowed action

checkPermission({role:'user'}, 'read', policies)
// returns: true

Constraints

  • Throw exactly `'Invalid role'` for any role not found as an own key of policies.
  • Throw exactly `'Permission denied'` for a valid role with no permission for the requested action.
  • Do not use the `in` operator or bracket access alone to check role existence.

Hint

References

solution.js
Ln 1, Col 1UTF-8JavaScript
Sandbox ready
0/0/0not run