An attack that defeats the OAuth2 state parameter's CSRF protection by fixing a known state value into the victim's session, so a callback carrying the attacker's authorization code passes the state...
OAuth2 State Fixation is an attack that defeats the state parameter's CSRF protection by fixing the value the victim's client will validate against. The attacker plants a state they know into the victim's session before the flow finishes, so a callback the attacker crafts, carrying the attacker's own authorization code, still passes the state check. It is the OAuth analogue of session fixation.
The OAuth2 State Parameter page covers the plain case: the client generates no state, or never compares it, so the attacker's callback is simply accepted. State fixation is the case where the client does generate and compare state, but stores the expected value somewhere the attacker can write, typically a cookie that is not bound to the authenticated session. The check runs and passes, because the attacker chose both sides of the comparison.
oauth_state) that is not tied to the server-side session.state.state to the fixed cookie value, they match, and it exchanges the attacker's code.// 1. Attacker fixes the victim's state cookie to a known value
// (e.g. cookie injection from sub.victim-app.com)
Set-Cookie: oauth_state=KNOWN123; Domain=victim-app.com
// 2. Attacker runs their own flow, code is bound to ATTACKER account,
// state chosen to match the fixed cookie
GET /authorize?response_type=code&client_id=app&state=KNOWN123&...
// -> code=ATTACKER_CODE
// 3. Victim is lured to the crafted callback
https://victim-app.com/callback?code=ATTACKER_CODE&state=KNOWN123
// 4. Client checks state == oauth_state cookie -> KNOWN123 == KNOWN123 -> passes
// It exchanges ATTACKER_CODE and links the victim's session
// to the attacker's identity provider account.
The payoff is forced account linking: the victim's logged-in account is now connected to the attacker's Google/GitHub identity, so the attacker can later sign in as the victim. If the callback drives login rather than linking, the victim is silently signed into the attacker's account and any data they enter lands in it.
__Host- prefix or an over-broad Domain lets a subdomain overwrite the cookie.__Host- cookie prefix with Secure and SameSite so a sibling subdomain cannot fix the value.