# CSRF via GET and path smuggling

State-changing actions reachable by GET, path traversal into API URLs, or CSRF tokens bound to the wrong scope

_Area: Web access control and IDOR. Seen in 5 disclosed reports; 3 confirmed bounties, median $500, range $300-$7,500; latest 2022-02-10. Updated 2026-10-23._

## How it works
A state-changing action is protected by an assumption that does not hold. Either the server trusts that mutations only arrive via POST with a token, or it trusts that a token proves the request came from the right user. When a client-side parameter is concatenated into an API URL, an attacker can encode a different endpoint or query into that parameter, turning a harmless GET into a mutation. When a token is derived from a shared resource instead of the user, any member of that resource can reuse it against another member.

## Where it shows up
- Route params (ids, slugs) concatenated into an API URL before the query string, with a forced suffix like `.json` or `?fields=`.
- OAuth callbacks or other same-origin GET endpoints that perform actions without CSRF token checks.
- CSRF tokens computed from a group/team/org id rather than the user or session.
- Parameters used in XHR URLs without type validation (e.g. integer ids).
- GraphQL or REST mutations reachable through GET.

## How to review
Check the invariant: every state-changing request must require a per-user, per-session token that the server verifies, and must not be reachable by GET. Trace each client param that flows into a URL builder; confirm it is validated or encoded so it cannot introduce a new path segment, query, or endpoint. For tokens, confirm the derivation input includes the acting user, not just the shared resource. For OAuth callbacks, confirm they reject requests lacking a valid state/token even on GET.

## Variants seen
- Path traversal in a route slug smuggling a GraphQL mutation into a GET [E1](https://bugbountylibrary.com/r/blog%3Aphilippeharewood-com-facebook-graphql-csrf.md).
- Traversal in an id parameter reaching an OAuth callback that skips CSRF checks on GET [E2](https://bugbountylibrary.com/r/h1%3A99708.md).
- CSRF hash bound to group_id, replayable by any editor against another [E3](https://bugbountylibrary.com/r/h1%3A315524.md).

## Impact and severity
Led to arbitrary mutations as the victim, forged integration requests, and impersonated messages. Severity rises when the smuggled action crosses privilege or tenant boundaries, and when tokens are shared across users so a low-privileged member can act as a higher one [E3](https://bugbountylibrary.com/r/h1%3A315524.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aphilippeharewood-com-facebook-graphql-csrf.md
- E2: https://bugbountylibrary.com/r/h1%3A99708.md
- E3: https://bugbountylibrary.com/r/h1%3A315524.md
