# Login CSRF using Twitter OAuth

Phabricator's Twitter OAuth 1.0a login lacked state, letting an attacker force a victim to log in as the attacker's account via a crafted callback URL.

- Payout: hidden
- Severity: medium
- Program: Phabricator
- Found by: mathias
- Disclosed: 2014-03-26
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/2228
- Library page: https://bugbountylibrary.com/r/h1%3A2228
- Tags: area:web domain:web impact:ato kind:bounty platform:hackerone sev:medium tech:oauth vuln:auth-bypass vuln:csrf

**Target:** OAuth login endpoint /auth/login/twitter:twitter.com/
**Root cause:** The Twitter OAuth authentication flow maintains no state parameter, so the callback with attacker's oauth_token/oauth_verifier is accepted without binding to the victim's session.
**Steps:**
1. Attacker initiates Twitter OAuth with Phabricator
2. Attacker allows access to the Phabricator app
3. Attacker records and drops the redirect to Phabricator to avoid consuming the token
4. Attacker sends victim to `/auth/login/twitter:twitter.com/?oauth_token={attacker_token}&oauth_verifier={attacker_verifier}`
5. Victim is logged in as the attacker's account
**How found:** Related to prior report #774 on logging a user into another account; recognized the Twitter OAuth flow lacks state, so a captured attacker callback could be replayed against a victim.
**Exploitation:** Attacker completes OAuth for their own account, captures the callback token/verifier without consuming it, and lures the victim to that callback URL, silently authenticating the victim into the attacker's Phabricator account.
**Insight:** OAuth 1.0a has no state param, but you can still bind the flow by embedding a per-session nonce inside the oauth_callback value and validating it on return; test login CSRF by capturing an unconsumed callback and replaying it to another browser.

