跨站请求伪造 (CSRF) 是什么 设计及工作原理

SQL注入和XSS攻击的是服务端/客户端代码 ,而CSRF(跨站请求伪造)攻击的是用户的浏览器身份认证机制

它们是Web安全领域的"三驾马车",但CSRF的设计机理和前两者完全不同------它不需要窃取数据 ,而是借用你的身份做坏事

下面我从设计本质攻击链路底层协议缺陷三个维度,为你彻底拆解CSRF。


第一部分:设计本质 ------ "信任的滥用"

CSRF的核心根因是:Web应用无法区分"用户本人发起的请求"和"用户不知情下由恶意网站发起的请求"

经典隐喻

  • 你(用户)登录了银行网站,浏览器保存了你的身份凭证(Cookie)

  • 你打开了一个恶意网页,该网页偷偷向银行网站发起转账请求。

  • 银行网站看到请求中带着你的Cookie,以为是你本人操作,于是执行了转账。

关键点 :CSRF不是通过窃取Cookie来冒充你(它根本拿不到你的Cookie),而是利用浏览器自动携带Cookie的机制,让银行网站"误以为"请求是你主动发起的。


第二部分:底层工作原理 ------ 攻击的"时空错位"

要理解CSRF,必须深入理解HTTP协议的无状态性浏览器的Cookie策略

1. 身份凭证的"自动携带"机制(CSRF的根源)

HTTP是无状态协议,为了识别用户,服务器在用户登录后返回一个Set-Cookie响应头,浏览器将Cookie保存下来。此后,浏览器在向该域名发起任何请求时(无论是点击链接、加载图片、还是AJAX请求),都会自动在请求头中携带该Cookie------这就是CSRF得以成立的根本。

2. 攻击的三步链路(经典攻击流程)

假设攻击者想在受害者不知情的情况下,修改其邮箱地址(常用于账号接管)。

  • 第一步(登录) :用户登录了 bank.com,浏览器得到 SESSIONID=abc123 的Cookie。

  • 第二步(诱导) :攻击者构造一个恶意页面 evil.com,内含一个隐藏表单或图片标签:

    html 复制代码
    <!-- 利用img标签自动加载,无需用户任何操作 -->
    <img src="https://bank.com/changeEmail?newEmail=hacker@evil.com" />

    或者更隐蔽的自动提交表单:

    html 复制代码
    <form action="https://bank.com/changeEmail" method="POST" id="hackForm">
      <input type="hidden" name="newEmail" value="hacker@evil.com" />
    </form>
    <script>document.getElementById('hackForm').submit();</script>
  • 第三步(执行) :用户访问了 evil.com,浏览器自动向 bank.com/changeEmail 发起请求,并自动携带SESSIONID=abc123 的Cookie。服务器验证Cookie通过,以为是用户本人操作,执行邮箱修改。

3. 为何同源策略防不住CSRF?

同源策略(SOP)确实限制了 evil.com 的JavaScript读取 bank.com 的Cookie或返回数据,但并不限制跨域请求的发起evil.com 可以通过 <img><script><form> 标签或 fetchbank.com 发送请求,浏览器会乖乖地附上Cookie------这就是"跨站请求"的由来。


第三部分:CSRF的三大变种(攻击手法升级)

类型 触发方式 隐蔽性 典型案例
GET型 利用 <img src="恶意URL"><a href="恶意URL"> 极高(用户甚至不需要点击,页面加载即触发) 银行转账、修改密码等GET接口
POST型 利用自动提交的隐藏 <form>fetch 极高(页面加载瞬间提交,用户无感知) 修改邮箱、添加管理员等POST接口
JSONP/跨域型 利用 script 标签加载JSONP接口 中(需要服务端支持JSONP回调) 早期一些API接口的CSRF漏洞

第四部分:终极防御 ------ 设计哲学与实现

CSRF的防御核心思想是:在请求中引入"服务端无法自动携带"的额外凭证,打破"Cookie自动携带"的信任链

1. CSRF Token(同步令牌)------ 最经典的防御

  • 设计原理 :服务端在用户登录后,生成一个随机且不可预测的Token(如UUID),存储在服务端Session或用户浏览器Cookie中,并将Token嵌入到每个表单或请求的隐藏字段或请求头中

  • 校验逻辑 :服务端处理请求时,同时校验Cookie中的SessionID和请求体/头中的Token 。由于Token是通过服务端生成的隐藏字段或请求头传递的,恶意网站 evil.com 无法获取这个Token(同源策略阻止其读取),因此无法伪造有效请求。

  • 关键细节 :Token绝不能只存在Cookie中(因为Cookie会被自动携带),必须放在请求体中或自定义请求头(如 X-CSRF-Token)中

2. SameSite Cookie属性(现代浏览器的杀手锏)

这是最优雅的防御方案,不需要后端任何代码改动

  • 设计原理 :服务端设置Cookie时,增加 SameSite 属性。

    • SameSite=Strict所有跨站请求(包括点击链接跳转)都不携带该Cookie。

    • SameSite=Lax(Chrome默认):部分安全跨站请求 (如 <a href> 跳转)携带,但POST表单、AJAX请求不携带。

  • 效果 :当用户从 evil.combank.com 发起请求时,如果Cookie设置了 SameSite,浏览器不会携带该Cookie,攻击自然失效。

3. 验证Referer/Origin头(辅助防御)

  • 原理 :检查请求头中的 RefererOrigin,确认请求来源是否为本站域。

  • 缺陷 :部分浏览器或网络环境可能不发送Referer头(如HTTPS->HTTP降级),且Referer可被篡改,因此不能作为唯一防御手段


第五部分:CSRF vs XSS ------ 攻防视角的终极对比

这是面试和日常开发中最容易混淆的两个概念,我用一张表彻底分清:

维度 CSRF(跨站请求伪造) XSS(跨站脚本攻击)
攻击目标 用户身份(借用用户的权限执行操作) 用户浏览器(在用户页面执行恶意脚本)
攻击前提 用户已登录目标网站(存在有效Cookie) 目标网站存在注入点(代码未过滤)
是否需要获取Cookie 不需要(仅利用浏览器自动携带Cookie的机制) 需要 (脚本运行时,通过 document.cookie 读取)
防御核心 引入不可自动携带的凭证(Token/SameSite) 输出编码 + CSP + HttpOnly
攻击后果 以用户身份执行操作(转账、改密、发帖) 窃取数据 + 劫持会话 + 篡改页面

第六部分:给开发者的"实战避坑指南"

  1. 所有状态变更请求(POST/PUT/DELETE) :必须启用CSRF防御,GET请求不应产生任何副作用(RESTful规范)。

  2. 前后端分离项目(SPA) :Token放在请求头(如 X-CSRF-Token)中传递,避免放在Cookie中。

  3. 老系统改造 :如果无法快速实现Token机制,优先设置 SameSite=Lax(兼容性极好,Chrome 80+、Firefox 79+、Safari 13+均支持)。

  4. 双重Cookie验证(Double Submit Cookie) :如果服务端无法存储Token,可以生成随机Token同时放入Cookie和请求头中,服务端校验两者是否一致(但需注意Cookie的 SameSite 保护)。

相关推荐
MoSTChillax1 小时前
UI规范设计:从视觉到交互的全面指南
前端·ui·产品经理·设计规范·vibecoding
雪碧聊技术1 小时前
Vue + Element Plus 实现文本溢出显示省略号及悬浮提示
前端·javascript·css·vue.js·文本溢出省略
eric-sjq2 小时前
0.6B 前端生成模型本地部署实战:消费级显卡跑通 WanlyFrontend 全流程
前端·本地部署
小妖6662 小时前
设置了 box-sizing: border-box; 不管用,下边框还是被挤压没了
前端·css·html
雪隐3 小时前
个人电脑玩AI-16让5060 Ti给你打工——5060Ti 16G 跑 MiniMax-Music-3:从下载到 60s 出歌的全流程
前端·人工智能·后端
CAD老兵4 小时前
让 AI Coding Agent 直接访问 CAD 文档:GitMCP 实战指南
前端·人工智能·github
程序员鱼皮4 小时前
DeepSeek Harness 最新邪修曝光!被吹成核弹的极简模式,真的夯吗?
前端·后端·ai编程
无己心4 小时前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
袅沫4 小时前
Nginx中部署多个前端项目——区分路径
服务器·前端