【浏览器原理——安全偏】什么是CSRF 如何防御?

8 阅读3分钟

一、CSRF攻击的定义与核心原理

CSRF(跨站请求伪造,Cross-Site Request Forgery)是一种利用用户对目标网站的信任发起的攻击。攻击者诱导用户在已登录目标网站的情况下,通过恶意请求(如链接、图片、表单等)执行非预期的操作。其本质是“冒充用户身份发起请求”。

攻击流程

  1. 用户登录信任网站(如银行网站 bank.com),并保持会话(Cookie有效)。
  2. 攻击者构造恶意请求(如转账操作),通过钓鱼链接、恶意页面等方式诱导用户触发。
  3. 用户浏览器自动携带Cookie向目标网站发送请求,服务器误认为是合法操作,导致攻击成功。

关键特征

  • 依赖用户已认证的会话(如Cookie)。
  • 攻击者无需窃取用户凭证,而是利用浏览器的自动发送凭证机制。

二、CSRF攻击的常见类型

1. GET型CSRF

  • 通过<img><iframe>等标签自动发起GET请求。

  • 示例

    <!-- 用户访问恶意页面时触发请求 -->  
    <img src="http://bank.com/transfer?to=attacker&amount=1000">
    

2. POST型CSRF

  • 通过隐藏表单或JavaScript自动提交POST请求。

  • 示例

    <form action="http://bank.com/transfer" method="POST" id="maliciousForm">  
      <input type="hidden" name="to" value="attacker">  
      <input type="hidden" name="amount" value="1000">  
    </form>  
    <script>document.getElementById('maliciousForm').submit();</script>
    

3. 其他变种

  • 结合XSS漏洞发起更复杂的攻击(如XSS+CSRF组合利用)。
  • 通过JSON劫持(需CORS配置不当)窃取敏感数据。

三、CSRF攻击的危害

  1. 用户账户篡改

    • 修改密码、绑定邮箱/手机号。
    • 更改收货地址或支付信息(如电商场景)。
  2. 资金操作

    • 发起转账、充值或提现请求(金融类应用)。
    • 自动购买商品或服务。
  3. 数据泄露或破坏

    • 删除用户数据(如社交平台内容)。
    • 触发敏感API调用(如开启设备远程控制)。

四、防御CSRF攻击的核心措施

1. CSRF Token(最常用)

  • 原理:服务器生成随机Token,嵌入表单或请求头中,提交时验证Token合法性。

  • 实现

    <!-- 服务端渲染时生成Token -->  
    <form action="/transfer" method="POST">  
      <input type="hidden" name="csrf_token" value="随机字符串">  
      <!-- 其他表单字段 -->  
    </form>
    
  • 验证逻辑:服务器比对请求中的Token与用户会话中存储的Token是否一致。

2. SameSite Cookie属性

  • 设置Cookie的SameSite属性为StrictLax,限制跨站请求携带Cookie。

  • HTTP响应头示例

    Set-Cookie: sessionId=abc123; SameSite=Lax; Secure
    

3. 检查Referer头

  • 验证请求来源域名是否合法(但可能被篡改或缺失)。

4. 二次验证

  • 对敏感操作(如转账)要求用户输入密码或短信验证码。

五、实际攻击与修复案例

攻击案例

假设银行转账接口未做CSRF防护:

<!-- 攻击者构造的恶意页面 -->  
<body onload="document.forms[0].submit()">  
  <form action="http://bank.com/transfer" method="POST">  
    <input type="hidden" name="to" value="attacker">  
    <input type="hidden" name="amount" value="10000">  
  </form>  
</body>

修复方案

  1. 添加CSRF Token

    <form action="/transfer" method="POST">  
      <input type="hidden" name="csrf_token" value="{{ csrf_token }}">  
      <!-- 其他字段 -->  
    </form>
    
  2. 服务端验证

    def transfer(request):  
        if request.POST.get('csrf_token') != request.session.get('csrf_token'):  
            return HttpResponseForbidden("Invalid CSRF Token")
        # 执行转账逻辑
    

六、与其他攻击的区别

  • CSRF vs XSS

    • XSS:攻击者在网站中注入脚本,利用用户对网站的信任(浏览器执行恶意代码)。
    • CSRF:攻击者伪造用户请求,利用网站对用户浏览器的信任(请求自动携带凭证)。
  • CSRF vs SSRF

    • CSRF:用户浏览器发起跨站请求(客户端层面)。
    • SSRF(服务器端请求伪造):攻击者利用服务器发起内部请求(服务端层面)。

总结

CSRF攻击的防御核心是“确保请求来自用户真实意图”。通过以下策略构建防护:

  1. CSRF Token:为每个会话生成唯一Token,验证请求合法性。
  2. SameSite Cookie:限制跨域请求自动携带Cookie。
  3. http请求头 多重验证:结合Referer检查、二次验证等多层措施。