Web安全:CSRF的攻击原理与防御措施

什么是 CSRF?

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用 浏览器自动携带 Cookie 的机制,诱骗用户在已登录目标网站的情况下,执行恶意操作的攻击方式。

攻击核心特点:

  • 攻击者 不需要窃取 Cookie,而是利用浏览器自动发送 Cookie 的机制。
  • 服务器无法区分 用户主动提交的请求和 恶意网站伪造的请求。

CSRF 攻击流程

示例场景(银行转账)

  1. 用户登录银行网站

    访问your-bank.com,服务器设置Cookie并返回:

    http 复制代码
    Set-Cookie: session_id=abc123; Secure; HttpOnly

    浏览器存储该 Cookie,后续访问 your-bank.com 时自动携带。

  2. 用户访问恶意网站

    恶意网站malicious.com隐藏了一个自动提交的表单:

    html 复制代码
       <form action="https://your-bank.com/transfer" method="POST">
         <input type="hidden" name="amount" value="10000">
         <input type="hidden" name="to_account" value="hacker">
       </form>
       <script>
         document.forms[0].submit(); // 自动提交
       </script>
  3. 浏览器发送伪造请求

    由于目标地址是your-bank.com,浏览器自动附加 Cookie

    http 复制代码
    POST /transfer HTTP/1.1
    Host: your-bank.com
    Cookie: session_id=abc123
    amount=10000&to_account=hacker

    服务器看到合法 session_id,执行转账,攻击成功!

CSRF 防御措施

(1)CSRF Token(最常用)

原理:服务器生成随机 Token,嵌入表单,提交时验证。

实现步骤:

  1. 服务器在渲染表单时生成 Token,存储(Session/Redis):

    html 复制代码
       <form action="/transfer" method="POST">
         <input type="hidden" name="csrf_token" value="RANDOM_STRING">
       </form>
  2. 提交请求时,服务器验证 Token 是否匹配:

    python 复制代码
       if request.cookies["session_id"] != user_session or request.form["csrf_token"] != stored_token:
           return "Invalid request!"
  3. 恶意网站无法获取 Token,伪造请求会被拒绝。

(2)SameSite Cookie(浏览器级防御)

通过设置 SameSite 属性,限制跨站请求携带 Cookie。

SameSite属性有三个值:

  • Strict模式‌(最严格、但可能影响用户体验)
    仅在请求来源与当前域名完全一致时发送Cookie,所有跨站请求均不携带。‌安全性最高,但可能影响用户体验(如从外部链接跳转时需重新登录)。‌‌
  • ‌Lax模式(推荐、默认值)
    允许在‌GET请求的顶级导航‌(如点击链接跳转)中发送Cookie,但禁止跨站的POST请求或其他非安全方法携带Cookie。‌‌平衡安全性与用户体验,成为主流浏览器的默认配置。‌‌

    http 复制代码
    Set-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Lax
  • None模式
    允许所有跨站点请求携带Cookie,但必须同时设置Secure属性(仅通过HTTPS传输)。‌‌

(3)检查 Referer/Origin 头

服务器检查 Referer(表示当前请求是从哪个 URL 页面发起的) 或 Origin (当前请求的 发起源,仅含协议 + 域名 + 端口,不含路径),判断请求来源是否合法。

缺点:Referer 可能被篡改或缺失,不适合作为唯一防护。