# OAuth2 authorization code injection: missing state parameter enables CSRF

- **ID:** `security/oauth2-state-parameter-missing`
- **Domain:** security
- **Category:** auth_error
- **Error Code:** `CSRF_TOKEN_MISSING`
- **Verification:** ai_generated
- **Fix Rate:** 92%

## Root Cause

The OAuth2 client does not generate or validate a cryptographically random state parameter, allowing an attacker to inject their own authorization code into a victim's session.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| OAuth2 2.0 RFC 6749 | active | — | — |
| Passport.js 0.6.0 | active | — | — |
| OmniAuth 2.1.0 | active | — | — |

## Workarounds

1. **Generate a cryptographically random state value per 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(authUrl + '&state=' + state);** (95% success)
   ```
   Generate a cryptographically random state value per 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(authUrl + '&state=' + state);
   ```
2. **Use PKCE (Proof Key for Code Exchange) with S256 challenge method, which inherently binds the authorization code to the client session** (90% success)
   ```
   Use PKCE (Proof Key for Code Exchange) with S256 challenge method, which inherently binds the authorization code to the client session
   ```
3. **Enforce state parameter validation at the authorization server level by rejecting requests without a valid nonce** (85% success)
   ```
   Enforce state parameter validation at the authorization server level by rejecting requests without a valid nonce
   ```

## Dead Ends

- **** — Static state is predictable and does not prevent CSRF; attacker can guess or reuse it. (95% fail)
- **** — Cookie-only state can be stolen via XSS or reused across sessions. (70% fail)
- **** — Redirect_uri matching does not prevent CSRF; attacker can still inject code via a pre-registered URI. (85% fail)
