CSRFValidationException security auth_error ai_generated true

CSRF token is not bound to the user session

ID: security/csrf-token-not-bound-to-session

Also available as: JSON · Markdown · 中文
90%Fix Rate
82%Confidence
1Evidence
2023-09-18First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Django 4.2 active
Spring Security 5.7 active
Flask-WTF 1.1 active
Express.js active

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.

generic

中文

CSRF 令牌是全局生成或按请求生成的,但未与会话绑定,允许攻击者跨会话预测或重用令牌。

Official Documentation

https://owasp.org/www-community/attacks/csrf

Workarounds

  1. 95% success 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.
    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.
  2. 90% success Use a framework's built-in CSRF protection, such as Django's `{% csrf_token %}` or Spring Security's `CsrfTokenRepository` with `HttpSessionCsrfTokenRepository`.
    Use a framework's built-in CSRF protection, such as Django's `{% csrf_token %}` or Spring Security's `CsrfTokenRepository` with `HttpSessionCsrfTokenRepository`.
  3. 85% success 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.
    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.

中文步骤

  1. 将会话中的 CSRF 令牌存储为每个会话的随机值。示例(Python Flask):`session['csrf_token'] = secrets.token_hex(32)` 并在视图中进行比较。
  2. 使用框架内置的 CSRF 保护,例如 Django 的 `{% csrf_token %}` 或 Spring Security 的 `CsrfTokenRepository` 配合 `HttpSessionCsrfTokenRepository`。
  3. 实现双重提交 Cookie:生成随机令牌,将其设置为 Cookie,并包含在隐藏的表单字段中;在服务器上验证两者是否匹配。

Dead Ends

Common approaches that don't work:

  1. 80% fail

    Using a static CSRF token for all users doesn't fix the issue; it makes the token easily guessable.

  2. 70% fail

    Only checking the token's presence, not its value, leaves the application vulnerable to token fixation.

  3. 60% fail

    Regenerating the token on every request without storing it in the session causes validation failures.