OIDC authorization request missing state parameter allows CSRF attack on callback
ID: security/oidc-state-parameter-missing-allows-csrf
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| OpenID Connect Core 1.0 | active | — | — | — |
| Keycloak 22.0.0 | active | — | — | — |
| Auth0 React SDK 2.0.0 | active | — | — | — |
| oidc-client-ts 2.4.0 | active | — | — | — |
| Spring Security OAuth2 Client 6.1.0 | active | — | — | — |
Root Cause
OpenID Connect authorization request does not include a cryptographically random 'state' parameter, enabling an attacker to inject an authorization code from their own session into the victim's callback, linking the victim's account to the attacker's identity.
generic中文
OpenID Connect 授权请求未包含加密随机的 'state' 参数,使攻击者能够将其自己会话中的授权代码注入受害者的回调,将受害者的帐户与攻击者的身份关联起来。
Official Documentation
https://openid.net/specs/openid-connect-core-1_0.html#AuthRequestWorkarounds
-
98% success Generate a cryptographically random state value for each authorization request and validate it in the callback. Example in Node.js using crypto: `const state = crypto.randomBytes(16).toString('hex'); session.state = state; res.redirect(`https://auth.example.com/authorize?state=${state}&...`);` and on callback: `if (req.query.state !== session.state) { reject('CSRF detected'); }`.
Generate a cryptographically random state value for each authorization request and validate it in the callback. Example in Node.js using crypto: `const state = crypto.randomBytes(16).toString('hex'); session.state = state; res.redirect(`https://auth.example.com/authorize?state=${state}&...`);` and on callback: `if (req.query.state !== session.state) { reject('CSRF detected'); }`. -
95% success Use a high-quality OIDC library that automatically handles state generation and validation (e.g., `openid-client` in Node.js or `oidc-client-ts` in JavaScript).
Use a high-quality OIDC library that automatically handles state generation and validation (e.g., `openid-client` in Node.js or `oidc-client-ts` in JavaScript).
中文步骤
Generate a cryptographically random state value for each authorization request and validate it in the callback. Example in Node.js using crypto: `const state = crypto.randomBytes(16).toString('hex'); session.state = state; res.redirect(`https://auth.example.com/authorize?state=${state}&...`);` and on callback: `if (req.query.state !== session.state) { reject('CSRF detected'); }`.Use a high-quality OIDC library that automatically handles state generation and validation (e.g., `openid-client` in Node.js or `oidc-client-ts` in JavaScript).
Dead Ends
Common approaches that don't work:
-
99% fail
A static state is predictable and can be reused by an attacker; it provides no CSRF protection.
-
85% fail
Nonce is verified in the ID token, but the authorization code exchange may occur before ID token validation; state is the primary CSRF defense for the code flow.
-
90% fail
Redirect URI binding does not prevent code injection; an attacker can still intercept the callback if the redirect URI is open to manipulation.