# Self-service scope and role escalation

Can a limited token or low role edit its own scope, role, or group membership?

_Area: Web access control and IDOR. Seen in 4 disclosed reports; one confirmed bounty: $1,000; latest 2026-05-05. Updated 2026-10-24._

## How it works
An endpoint that manages credentials or permissions (tokens, roles, group membership) accepts the very principal it is supposed to govern. The check confirms "is this a valid caller?" but never asks "is this caller allowed to change its own ceiling?" So a limited credential or low role reaches the management API and grants itself more than it had. The broken assumption: that only a full login session or a higher role would ever call the management endpoint.

## Where it shows up
- Token/credential endpoints (e.g. `/settings/personal/authtokens/{id}`) reachable with the same scoped token being edited [E1](https://bugbountylibrary.com/r/h1%3A1193321.md)
- PUT/PATCH on a token, role, or membership object where the caller equals the target
- Capability filters that deny only one role (e.g. `administrator`) instead of allow-listing [E2](https://bugbountylibrary.com/r/h1%3A403039.md)
- `edit_users`-style caps held by mid-tier roles like Shop manager [E2](https://bugbountylibrary.com/r/h1%3A403039.md)
- GraphQL mutations assigning group membership, especially auto-created default admin groups [E3](https://bugbountylibrary.com/r/h1%3A2372018.md)
- Newly provisioned tenants/programs whose default groups skip the authorization checks applied to custom ones [E3](https://bugbountylibrary.com/r/h1%3A2372018.md)

## How to review
For every endpoint that writes scope, role, or membership, check two invariants:
1. **No self-elevation:** the caller cannot be the object being modified, or the change cannot exceed the caller's own ceiling. A scoped token must not be able to widen its own scope [E1](https://bugbountylibrary.com/r/h1%3A1193321.md).
2. **Re-auth for sensitive changes:** scope/role changes require a real password+2FA session, not just any valid token [E1](https://bugbountylibrary.com/r/h1%3A1193321.md).
For role systems, verify the filter is an allow-list of assignable roles, not a deny-list of one role [E2](https://bugbountylibrary.com/r/h1%3A403039.md). Enumerate every role on the install, including plugin-registered ones. For group mutations, confirm authorization runs on default/auto-created groups, not only custom ones [E3](https://bugbountylibrary.com/r/h1%3A2372018.md).

## Variants seen
- Scoped app token widens its own scope via the token-management endpoint [E1](https://bugbountylibrary.com/r/h1%3A1193321.md)
- Blacklist capability filter lets a mid-tier role assign any non-admin role [E2](https://bugbountylibrary.com/r/h1%3A403039.md)
- GraphQL mutation lets a low role add itself to default admin groups [E3](https://bugbountylibrary.com/r/h1%3A2372018.md)

## Impact and severity
Full file access from a filesystem-scoped token [E1](https://bugbountylibrary.com/r/h1%3A1193321.md); privilege escalation to editor and stored XSS via `unfiltered_html` [E2](https://bugbountylibrary.com/r/h1%3A403039.md); escalation to report manager or full program admin [E3](https://bugbountylibrary.com/r/h1%3A2372018.md). Severity rises when the widened credential is long-lived (tokens) or when default groups are auto-created and assumed safe.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1193321.md
- E2: https://bugbountylibrary.com/r/h1%3A403039.md
- E3: https://bugbountylibrary.com/r/h1%3A2372018.md
