OIDC 授权请求缺少 state 参数,允许对回调进行 CSRF 攻击
OIDC authorization request missing state parameter allows CSRF attack on callback
ID: security/oidc-state-parameter-missing-allows-csrf
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 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 | — | — | — |
根因分析
OpenID Connect 授权请求未包含加密随机的 'state' 参数,使攻击者能够将其自己会话中的授权代码注入受害者的回调,将受害者的帐户与攻击者的身份关联起来。
English
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.
官方文档
https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest解决方案
-
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).
无效尝试
常见但无效的做法:
-
99% 失败
A static state is predictable and can be reused by an attacker; it provides no CSRF protection.
-
85% 失败
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% 失败
Redirect URI binding does not prevent code injection; an attacker can still intercept the callback if the redirect URI is open to manipulation.