# Weaker permission satisfies privileged check

Permission checks where a weaker, implied, or zero-valued grant passes a check meant for a stronger one

_Area: Web access control and IDOR. Seen in 2 disclosed reports; latest 2026-10-09. Updated 2026-10-23._

## How it works
A handler intends to require a strong permission (admin, manageUsers, operator) but the check it actually performs can be satisfied by something weaker. Two shapes recur in the evidence: the wrong permission constant is named, or the required value is a zero sentinel that makes a bitmask AND vacuously true. The assumption that breaks is "this check means what its name says." The check passes for principals the author never intended.

## Where it shows up
- Permission decorators/annotations whose required value is `ANY`, `public`, or `0` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md)
- Bitmask checks of the form `required == (user & required)` where required can be 0 [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md)
- Handlers authorizing with `update`/`read` where the operation is `manage`/`delete` [E1](https://bugbountylibrary.com/r/blog%3Agithub-blog-security-how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework.md)
- Admin-only wrappers reachable through a weaker-decorated public endpoint [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md)
- Shared admin controllers where auth is set at controller level but actions differ in privilege [E3](https://bugbountylibrary.com/r/h1%3A2197796.md)
- Bootstrap/start/reset endpoints with privileged side effects [E3](https://bugbountylibrary.com/r/h1%3A2197796.md)

## How to review
For each privileged operation, name the exact permission it requires and confirm the check enforces that same permission, not a weaker or implied one. The invariant: a check passes only if the principal holds the specific grant the operation demands; no sentinel, zero, or broader role may satisfy it. Verify per-action gating on shared controllers, not just controller-level auth [E3](https://bugbountylibrary.com/r/h1%3A2197796.md). Trace the required value through the comparison: if it can be zero or empty, the check is vacuous [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md).

## Variants seen
- Wrong permission constant: `update` used where `manageUsers` required [E1](https://bugbountylibrary.com/r/blog%3Agithub-blog-security-how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework.md)
- Zero sentinel: `Perms.ANY==0` makes bitmask check vacuous, exposing admin-only wrapper [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md)
- Missing per-action role gate on admin console route [E3](https://bugbountylibrary.com/r/h1%3A2197796.md)

## Impact and severity
Privilege escalation to site admin [E3](https://bugbountylibrary.com/r/h1%3A2197796.md), admin password oracle and brute-force [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md), group-membership escalation and guest PII leaks [E1](https://bugbountylibrary.com/r/blog%3Agithub-blog-security-how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework.md). Severity rises when the weaker principal is broadly available (any authenticated user) and the privileged effect is account takeover or admin reset.

## Why fixes fail
Fixing one route leaves sibling actions on the same controller ungated [E3](https://bugbountylibrary.com/r/h1%3A2197796.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Agithub-blog-security-how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-68w4-83fh-f2w8.md
- E3: https://bugbountylibrary.com/r/h1%3A2197796.md
