code4f 2025-11-23 19:25 采纳率: 98.9%
浏览 0
已采纳

CSRF令牌如何防止伪造请求?

CSRF令牌如何防止伪造请求?一个常见问题是:当Web应用未正确验证或缺失同步CSRF令牌时,攻击者可构造恶意页面,在用户登录状态下诱导其点击链接或访问页面,从而以用户身份发起非预期的请求(如转账、改密)。CSRF令牌通过为每个用户会话生成唯一、不可预测的随机值,并嵌入表单或请求头中,确保服务器仅接受携带合法令牌的请求。由于同源策略限制,攻击者无法获取目标站点的令牌,因而伪造请求无法通过验证,有效阻断跨站请求伪造攻击。
  • 写回答

1条回答 默认 最新

  • 希芙Sif 2025-11-23 19:25
    关注

    1. CSRF攻击的基本原理与风险场景

    跨站请求伪造(Cross-Site Request Forgery, CSRF)是一种利用用户在已认证状态下的会话发起非预期操作的攻击方式。当用户登录目标网站(如银行系统)后,攻击者诱导其访问恶意页面,该页面自动向目标站点提交请求(例如转账、修改密码),由于浏览器自动携带用户的Cookie,服务器误认为是合法请求。

    典型攻击流程如下:

    1. 用户登录银行A并保持会话(Cookie已存储)
    2. 用户访问攻击者控制的恶意网站B
    3. 网站B包含一个隐藏的表单或自动提交的请求,指向银行A的转账接口
    4. 浏览器自动携带用户身份凭证(Cookie)发送请求
    5. 银行A服务器处理请求,完成转账操作

    此过程无需用户交互确认,即可完成敏感操作,构成严重安全威胁。

    2. CSRF令牌的核心防御机制

    CSRF令牌是一种服务端生成的随机字符串,绑定到用户会话中,并嵌入到每个需要防护的表单或AJAX请求头中。服务器在接收到请求时,必须验证该令牌的有效性。

    要素说明
    唯一性每个用户会话拥有独立的令牌
    不可预测性使用加密安全的随机数生成器(如/dev/urandom)
    同步机制服务端存储预期值,客户端提交实际值进行比对
    传输方式通常通过隐藏字段、自定义Header(如X-CSRF-Token)传递

    3. 技术实现细节与代码示例

    以下是一个典型的CSRF令牌生成与验证流程的伪代码实现:

    
    import os
    import secrets
    from flask import session, request, abort
    
    # 生成CSRF令牌
    def generate_csrf_token():
        if 'csrf_token' not in session:
            session['csrf_token'] = secrets.token_hex(32)
        return session['csrf_token']
    
    # 验证CSRF令牌
    def validate_csrf_token():
        token = request.form.get('csrf_token') or \
                request.headers.get('X-CSRF-Token')
        if not token or token != session.get('csrf_token'):
            abort(403)  # Forbidden
      

    在HTML模板中注入令牌:

    
    <form method="POST" action="/transfer">
      <input type="hidden" name="csrf_token" value="{{ generate_csrf_token() }}" />
      <input type="text" name="amount" />
      <button type="submit">Transfer</button>
    </form>
      

    4. 同源策略的关键作用分析

    CSRF防御之所以有效,关键在于浏览器的同源策略(Same-Origin Policy)。攻击者无法通过JavaScript读取目标站点响应内容,因此不能获取嵌入在页面中的CSRF令牌。

    即使攻击者能诱导用户发起请求,也无法构造出包含正确令牌的请求体,因为:

    • 无法通过AJAX跨域读取目标页面的CSRF令牌
    • 无法预知服务端生成的随机值
    • 表单提交需显式包含令牌字段

    这使得伪造请求在缺乏有效令牌的情况下被服务端拒绝。

    5. 常见漏洞模式与误配置案例

    尽管CSRF令牌广泛使用,但以下常见问题仍会导致防护失效:

    问题类型描述修复建议
    令牌缺失某些API路径未启用CSRF校验全局中间件统一校验
    弱随机性使用时间戳或可预测算法生成令牌采用CSPRNG(密码学安全伪随机数生成器)
    令牌绑定错误多个用户共享同一令牌确保令牌与session强绑定
    Token泄露通过URL参数传递导致日志暴露避免GET请求携带Token,使用POST+Body/Header

    6. 高级防御策略与架构演进

    现代Web应用结合多种机制增强CSRF防护:

    • Synchronizer Token Pattern (STP):传统方案,适用于服务端渲染
    • Double Submit Cookie:将令牌同时写入Cookie和请求头,适合无状态API
    • SameSite Cookie属性:设置SameSite=Strict/Lax限制第三方上下文发送Cookie

    推荐组合使用:

    
    Set-Cookie: XSRF-TOKEN=abc123...; Path=/; SameSite=Strict; Secure; HttpOnly=false
    

    前端从Cookie读取并放入请求头:

    
    axios.defaults.xsrfCookieName = 'XSRF-TOKEN';
    axios.defaults.xsrfHeaderName = 'X-CSRF-Token';
    

    7. 攻防流程可视化:CSRF攻击与防御对比

    下图为CSRF攻击与防御机制的流程对比:

    graph TD A[用户登录目标站点] --> B[会话建立,Cookie存储] B --> C{是否启用CSRF令牌?} C -->|否| D[攻击者构造恶意请求] D --> E[浏览器自动携带Cookie] E --> F[服务器执行非预期操作] C -->|是| G[服务端生成唯一CSRF令牌] G --> H[令牌嵌入表单/头部] H --> I[用户提交请求] I --> J[服务端比对令牌] J --> K{匹配?} K -->|是| L[处理请求] K -->|否| M[拒绝请求,返回403]
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 11月24日
  • 创建了问题 11月23日