# Missing role hierarchy in permission updates

Endpoints that write roles, passwords or permissions without comparing caller level to granted level

_Area: Web access control and IDOR. Seen in 2 disclosed reports; latest 2026-05-29. Updated 2026-11-01._

## How it works
An endpoint that grants a role, permission or credential checks only that the caller is *some* authenticated user (or member), never that the caller outranks what is being granted. The authorization gate exists but is called in a form that cannot enforce a minimum level, or the write path bypasses the hierarchy helper entirely. The broken assumption: "authenticated" or "member" implies "allowed to change privilege." It does not.

## Where it shows up
- Role/membership update routes (PATCH/PUT on member rows) that accept a `role` field from the body.
- Dependency functions with a tunable `min_role`/`required_role` parameter used as bare `Depends(fn)` with no wrapper, so the default (lowest) applies [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md).
- Password-change endpoints that validate session existence but not current password or auth method [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).
- Signup/defaults handlers that copy a whole permission struct and strip only one field (e.g. Admin) [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md).
- Auth-migration code that deactivates old credential rows instead of deleting them [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).
- Login-method selection taken from client input without checking the row is active [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).

## How to review
Find every write to a role, permission or credential field. For each, confirm the invariant: **the caller's level must be strictly greater than (or equal to policy) the level being granted, and the target must be within the caller's scope.** Check that:
- The route actually invokes the hierarchy helper (`has_role`, rank comparison) before writing [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md).
- Dependency parameters are supplied via a wrapper, not left at default [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md).
- Credential changes require proof of the current credential or a privileged caller [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).
- Default-permission application enumerates every privileged field, not just Admin [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md).
- Deactivated credentials cannot be written to or selected [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).

## How finders spotted it
- Noticed `require_workspace_member` exposed a `min_role` parameter no route overrode, while `has_role` implemented a hierarchy `update_role` never called — the asymmetry was the tell [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md).
- Code-read account routes and migration logic: `change-password` lacked `isAdmin()`, `enableOpenID()` set `active=0` without deleting the password row, and `getLoginMethod()` trusted client input [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).
- Saw a prior Admin-only fix, then read `Defaults.Apply` and `signupHandler` to find Execute/Commands copied but never stripped, tracing `commandsHandler` to confirm persisted values are authoritative [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md).

## Variants seen
- Self-promotion via own membership row to owner [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md).
- Password overwrite on an orphaned credential row plus client-chosen login method [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md).
- Signup inheriting execution permissions from defaults [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md).

## Impact and severity
Full workspace takeover enabling member/settings control and chaining into delete/IDOR for data exfiltration [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md); BASIC-to-ADMIN escalation on migrated servers [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md); shell execution and server compromise when running as root, otherwise lateral movement and secret/file access [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md). Impact rises with chaining and with process privilege.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-prp4-2f49-fcgp.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-c2m8-4gcg-v22g.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-x8jc-jvqm-pm3f.md
