# Client-supplied privileged state trusted

Handlers accepting client-sent status, role, or permission fields without server-side authorization checks

_Area: Web access control and IDOR. Seen in 4 disclosed reports; 2 confirmed bounties: $500 and $1,000; latest 2026-07-07. Updated 2026-10-24._

## How it works
A handler reads a privileged attribute (status, role, permission, official flag) from the same client request that carries ordinary data, and applies it without checking it against server-side state or the caller's role. The broken assumption is that the client only sends values the server would allow. Any user who can reach the endpoint can set the value directly.

## Where it shows up
- GraphQL mutations with variables named `status`, `state`, `role`, `permissions`, `participant_role` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md)[E3](https://bugbountylibrary.com/r/h1%3A1861487.md)[E4](https://bugbountylibrary.com/r/h1%3A1088159.md)
- Workflow state transitions where the target state is a request field, especially around moderation gates [E3](https://bugbountylibrary.com/r/h1%3A1861487.md)
- Structured attribute arrays or index-based flag lists sent by the client [E1](https://bugbountylibrary.com/r/h1%3A1653676.md)
- ACL values read from the same JSON body as the upload or action metadata [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md)
- Permission arrays mixing a sentinel like FULL/ALL with granular tokens [E4](https://bugbountylibrary.com/r/h1%3A1088159.md)

## How to review
For each privileged field, trace where its value originates. The invariant: the effective value of any role, status, or permission must be derived from server-side records tied to the authenticated caller, never from request input. Check that the state-transition mutation enforces the allowed prior state and target state server-side [E3](https://bugbountylibrary.com/r/h1%3A1861487.md). Check that permission arrays are validated as a whole, with unknown tokens rejected rather than dropped [E4](https://bugbountylibrary.com/r/h1%3A1088159.md). Check that ACL decisions use stored enrollment, not a body field [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md). Check that flag indices in attribute arrays are validated against caller privilege [E1](https://bugbountylibrary.com/r/h1%3A1653676.md).

## Variants seen
- Client-set official/recommended flags in a competition attribute array [E1](https://bugbountylibrary.com/r/h1%3A1653676.md)
- `participant_role` in upload body driving teacher ACL, chained with path traversal [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md)
- GraphQL `status` variable bypassing admin moderation [E3](https://bugbountylibrary.com/r/h1%3A1861487.md)
- `permissions` array accepting FULL sentinel alongside granular tokens [E4](https://bugbountylibrary.com/r/h1%3A1088159.md)

## Why fixes fail
In [E4](https://bugbountylibrary.com/r/h1%3A1088159.md), invalid tokens were silently ignored, so stale FULL access persisted even after partial fixes; validation must reject unknowns, not skip them.

## Impact and severity
Ranged from content spoofing [E1](https://bugbountylibrary.com/r/h1%3A1653676.md) and moderation bypass [E3](https://bugbountylibrary.com/r/h1%3A1861487.md) to full privilege escalation [E4](https://bugbountylibrary.com/r/h1%3A1088159.md) and remote code execution via chained file write [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md). Severity rose where the trusted field fed an ACL or filesystem path, and where a companion endpoint amplified the write.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1653676.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-h9qx-v5xp-ph8p.md
- E3: https://bugbountylibrary.com/r/h1%3A1861487.md
- E4: https://bugbountylibrary.com/r/h1%3A1088159.md
