{
  "id": "security/csrf-token-not-bound-to-session",
  "signature": "CSRF token is not bound to the user session",
  "signature_zh": "CSRF 令牌未绑定到用户会话",
  "regex": "CSRF.*(?:not bound|session|token mismatch|invalid)",
  "domain": "security",
  "category": "auth_error",
  "subcategory": null,
  "root_cause": "The CSRF token is generated globally or per-request but not tied to the session, allowing an attacker to predict or reuse a token across sessions.",
  "root_cause_type": "generic",
  "root_cause_zh": "CSRF 令牌是全局生成或按请求生成的，但未与会话绑定，允许攻击者跨会话预测或重用令牌。",
  "versions": [
    {
      "version": "Django 4.2",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Spring Security 5.7",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Flask-WTF 1.1",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Express.js",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "",
      "why_fails": "Using a static CSRF token for all users doesn't fix the issue; it makes the token easily guessable.",
      "fail_rate": 0.8,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "Only checking the token's presence, not its value, leaves the application vulnerable to token fixation.",
      "fail_rate": 0.7,
      "condition": "",
      "sources": []
    },
    {
      "action": "",
      "why_fails": "Regenerating the token on every request without storing it in the session causes validation failures.",
      "fail_rate": 0.6,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Store the CSRF token in the session and generate a random value per session. Example (Python Flask): `session['csrf_token'] = secrets.token_hex(32)` and compare it in the view.",
      "success_rate": 0.95,
      "how": "Store the CSRF token in the session and generate a random value per session. Example (Python Flask): `session['csrf_token'] = secrets.token_hex(32)` and compare it in the view.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use a framework's built-in CSRF protection, such as Django's `{% csrf_token %}` or Spring Security's `CsrfTokenRepository` with `HttpSessionCsrfTokenRepository`.",
      "success_rate": 0.9,
      "how": "Use a framework's built-in CSRF protection, such as Django's `{% csrf_token %}` or Spring Security's `CsrfTokenRepository` with `HttpSessionCsrfTokenRepository`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Implement double-submit cookies: generate a random token, set it as a cookie, and include it in a hidden form field; verify both match on the server.",
      "success_rate": 0.85,
      "how": "Implement double-submit cookies: generate a random token, set it as a cookie, and include it in a hidden form field; verify both match on the server.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "将会话中的 CSRF 令牌存储为每个会话的随机值。示例（Python Flask）：`session['csrf_token'] = secrets.token_hex(32)` 并在视图中进行比较。",
    "使用框架内置的 CSRF 保护，例如 Django 的 `{% csrf_token %}` 或 Spring Security 的 `CsrfTokenRepository` 配合 `HttpSessionCsrfTokenRepository`。",
    "实现双重提交 Cookie：生成随机令牌，将其设置为 Cookie，并包含在隐藏的表单字段中；在服务器上验证两者是否匹配。"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://owasp.org/www-community/attacks/csrf",
  "official_doc_section": null,
  "error_code": "CSRFValidationException",
  "verification_tier": "ai_generated",
  "confidence": 0.82,
  "fix_success_rate": 0.9,
  "resolvable": "true",
  "first_seen": "2023-09-18",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}