CSRF_TOKEN_MISSING security auth_error ai_generated true

OAuth2 authorization code injection: missing state parameter enables CSRF

ID: security/oauth2-state-parameter-missing

Also available as: JSON · Markdown · 中文
92%Fix Rate
90%Confidence
1Evidence
2023-05-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
OAuth2 2.0 RFC 6749 active
Passport.js 0.6.0 active
OmniAuth 2.1.0 active

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.

generic

中文

OAuth2客户端未生成或验证加密随机的state参数,使攻击者可以将自己的授权码注入到受害者的会话中。

Official Documentation

https://datatracker.ietf.org/doc/html/rfc6749#section-10.12

Workarounds

  1. 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);
    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. 90% success Use PKCE (Proof Key for Code Exchange) with S256 challenge method, which inherently binds the authorization code to the client session
    Use PKCE (Proof Key for Code Exchange) with S256 challenge method, which inherently binds the authorization code to the client session
  3. 85% success Enforce state parameter validation at the authorization server level by rejecting requests without a valid nonce
    Enforce state parameter validation at the authorization server level by rejecting requests without a valid nonce

中文步骤

  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);
  2. 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

Dead Ends

Common approaches that don't work:

  1. 95% fail

    Static state is predictable and does not prevent CSRF; attacker can guess or reuse it.

  2. 70% fail

    Cookie-only state can be stolen via XSS or reused across sessions.

  3. 85% fail

    Redirect_uri matching does not prevent CSRF; attacker can still inject code via a pre-registered URI.