{
  "id": "security/oidc-state-parameter-missing-allows-csrf",
  "signature": "OIDC authorization request missing state parameter allows CSRF attack on callback",
  "signature_zh": "OIDC 授权请求缺少 state 参数，允许对回调进行 CSRF 攻击",
  "regex": "missing state parameter|state parameter not found|CSRF via OAuth callback",
  "domain": "security",
  "category": "auth_error",
  "subcategory": null,
  "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.",
  "root_cause_type": "generic",
  "root_cause_zh": "OpenID Connect 授权请求未包含加密随机的 'state' 参数，使攻击者能够将其自己会话中的授权代码注入受害者的回调，将受害者的帐户与攻击者的身份关联起来。",
  "versions": [
    {
      "version": "OpenID Connect Core 1.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Keycloak 22.0.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Auth0 React SDK 2.0.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "oidc-client-ts 2.4.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Spring Security OAuth2 Client 6.1.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "",
      "why_fails": "A static state is predictable and can be reused by an attacker; it provides no CSRF protection.",
      "fail_rate": 0.99,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "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.",
      "fail_rate": 0.85,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "Redirect URI binding does not prevent code injection; an attacker can still intercept the callback if the redirect URI is open to manipulation.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "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'); }`.",
      "success_rate": 0.98,
      "how": "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'); }`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "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).",
      "success_rate": 0.95,
      "how": "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).",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "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)."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest",
  "official_doc_section": null,
  "error_code": "OIDC_MISSING_STATE",
  "verification_tier": "ai_generated",
  "confidence": 0.9,
  "fix_success_rate": 0.95,
  "resolvable": "true",
  "first_seen": "2023-11-05",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}