# OAuth2 state parameter reuse allows CSRF via replay attack

- **ID:** `security/oauth2-state-parameter-replay-attack`
- **Domain:** security
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 88%

## Root Cause

When the OAuth2 state parameter is not bound to a specific user session or is reused across multiple authorization requests, an attacker can replay a captured authorization response to bind a victim's account to the attacker's session.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| OAuth2 2.0 | active | — | — |
| Spring Security OAuth2 5.8.0 | active | — | — |
| Passport.js 0.7.0 | active | — | — |

## Workarounds

1. **Generate a cryptographically random state value per authorization request, store it in the user session, and validate it on callback. Example in Node.js: const state = crypto.randomBytes(16).toString('hex'); req.session.oauthState = state; res.redirect(`https://provider/authorize?response_type=code&client_id=...&state=${state}`);** (98% success)
   ```
   Generate a cryptographically random state value per authorization request, store it in the user session, and validate it on callback. Example in Node.js: const state = crypto.randomBytes(16).toString('hex'); req.session.oauthState = state; res.redirect(`https://provider/authorize?response_type=code&client_id=...&state=${state}`);
   ```
2. **Use a nonce-like mechanism where state includes a timestamp and user ID, signed with a server secret, to prevent replay.** (85% success)
   ```
   Use a nonce-like mechanism where state includes a timestamp and user ID, signed with a server secret, to prevent replay.
   ```

## Dead Ends

- **Using a static state value for all users** — A static state is predictable and can be easily forged by an attacker; it doesn't provide CSRF protection. (100% fail)
- **Generating state but not storing it in the session** — Without session binding, the state cannot be verified on callback; any state value is accepted, enabling replay. (95% fail)
