# CSRF on cookie-authenticated write endpoints

State-changing endpoints trusting ambient cookies without a token, Origin check, or preflight barrier

_Area: Web authentication and account takeover. Seen in 20 disclosed reports; 11 confirmed bounties, median $2,400, range $100-$6,000; latest 2024-06-25. Updated 2026-10-23._

## How it works

A state-changing endpoint treats the browser's ambient cookie as proof of user intent. The attacker's page cannot read the response, but it can still send the request, and the victim's cookie rides along. The broken assumption: "only our own pages can send this request." That holds only if the server requires a per-request secret the attacker's origin cannot obtain, or rejects cross-origin requests via Origin/Referer, or forces a CORS preflight. Control-channel APIs that authenticate by cookie alone (bind/pair endpoints) fall to the same root cause [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-04-05-i-built-a-tv-that-plays-all-of-your-private-youtube-videos.md).

## Where it shows up

- POST/PATCH/PUT/DELETE handlers with cookie auth and no token at all, including method-override paths [E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md).
- JSON APIs accepting `text/plain` or form-urlencoded bodies, which are CORS-simple and skip preflight [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E5](https://bugbountylibrary.com/r/h1%3A1466765.md).
- Framework method overrides (`_method=patch`) letting a plain HTML form reach PATCH/PUT [E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md).
- MFA/2FA enrollment and recovery endpoints that skip the CSRF crumb other endpoints enforce [E3](https://bugbountylibrary.com/r/h1%3A155774.md).
- SameSite=Lax assumed as defense: it blocks cross-site but not same-site sibling origins on the same registrable domain [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E8](https://bugbountylibrary.com/r/h1%3A1458236.md).
- One handler multiplexing many privileged actions via an `action` parameter [E6](https://bugbountylibrary.com/r/blog%3Ahesec-de-posts-bbh-csrf.md).
- Per-tenant config (`cookie_samesite`, `allow_embedding`) letting an attacker tenant weaken cookie protections [E8](https://bugbountylibrary.com/r/h1%3A1458236.md).
- CSRF checks enforced only for HTML responses, skipped for `.json`/`.xml` paths or extensions.
- Content-Type checks that a forged request can satisfy (e.g. a redirect/plugin trick that sets a JSON Content-Type).

## How to review

For every state-changing endpoint, establish the invariant: a request is honored only if it carries a secret the attacker's origin cannot obtain, or the server rejects it on Origin/Referer. Grep for the token-extraction source and confirm it reads a header or non-tossable source, not URL/body. Confirm Origin/Referer validation actually exists and rejects missing or foreign values, not just reflects them, and is anchored (no prefix/regex bypass) [E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md). Enumerate every content type the backend actually parses, not just the documented one [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E5](https://bugbountylibrary.com/r/h1%3A1466765.md). Check whether the framework honors method-override params and urlencoded bodies [E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md). Verify the CSRF check runs on every response format and path, not only HTML. Test cookie scope against real sibling subdomains; SameSite=Lax is not a CSRF defense for same-site sibling origins [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E8](https://bugbountylibrary.com/r/h1%3A1458236.md). Audit MFA enrollment/recovery separately from login [E3](https://bugbountylibrary.com/r/h1%3A155774.md).

## Variants seen

- Cookie-only control/bind API with no token, leaking private video IDs [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-04-05-i-built-a-tv-that-plays-all-of-your-private-youtube-videos.md).
- MFA SMS enrollment ignoring the CSRF crumb, converting a stolen password into full ATO [E3](https://bugbountylibrary.com/r/h1%3A155774.md).
- text/plain JSON accepted without preflight, chained to admin invite or cluster compromise [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E5](https://bugbountylibrary.com/r/h1%3A1466765.md).
- Method-override form reaching PATCH to change email/password [E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md).
- Single `action`-parameter handler chaining four privileged POSTs [E6](https://bugbountylibrary.com/r/blog%3Ahesec-de-posts-bbh-csrf.md).
- Attacker-tenant config weakening SameSite on a shared platform [E8](https://bugbountylibrary.com/r/h1%3A1458236.md).
- Unanchored Referer regex bypassed by lookalike host [E4](https://bugbountylibrary.com/r/h1%3A975983.md).

## Impact and severity

Outcomes ranged from private data disclosure [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-04-05-i-built-a-tv-that-plays-all-of-your-private-youtube-videos.md) and account takeover via email/password or MFA change [E3](https://bugbountylibrary.com/r/h1%3A155774.md)[E7](https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md) to admin invite and full cluster compromise [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md)[E5](https://bugbountylibrary.com/r/h1%3A1466765.md). Severity tracks the privilege of the CSRF'd action: admin invite, app deploy, or cluster compromise [E2](https://bugbountylibrary.com/r/h1%3A2326194.md)[E4](https://bugbountylibrary.com/r/h1%3A975983.md) outranks a read-only leak [E1](https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-04-05-i-built-a-tv-that-plays-all-of-your-private-youtube-videos.md). Missing Origin checks, permissive content types, and same-site sibling origins widened reach.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Abugs-xdavidhu-me-google-2021-04-05-i-built-a-tv-that-plays-all-of-your-private-youtube-videos.md
- E2: https://bugbountylibrary.com/r/h1%3A2326194.md
- E3: https://bugbountylibrary.com/r/h1%3A155774.md
- E4: https://bugbountylibrary.com/r/h1%3A975983.md
- E5: https://bugbountylibrary.com/r/h1%3A1466765.md
- E6: https://bugbountylibrary.com/r/blog%3Ahesec-de-posts-bbh-csrf.md
- E7: https://bugbountylibrary.com/r/blog%3Awebs3c-com-t-csrf-leads-to-account-takeover-in-yahoo-93.md
- E8: https://bugbountylibrary.com/r/h1%3A1458236.md
