XSS与CSRF攻击有何本质区别?

1 人参与

很多开发者在面试时被问到这个问题,往往只能憋出一句:"XSS是注入脚本,CSRF是伪造请求。"话虽没错,但这种回答就像被问及"汽油车和电动车的区别"时回答"一个烧油一个用电"一样,只触及了皮毛。要真正理解两者的本质差异,需要从信任链的破坏点入手。

信任关系的错位:谁在欺骗谁?

XSS(跨站脚本攻击)的核心在于"背叛用户的信任"。浏览器无条件信任从服务器接收到的内容,攻击者正是利用这一点,将恶意代码伪装成正常内容注入页面。当受害者的浏览器执行这段代码时,实际上是在执行攻击者的指令,但浏览器误以为这是来自可信服务器的合法脚本。这就好比有人在你购买的密封牛奶盒里注射了毒药,你毫无防备地喝下去,因为你信任那个品牌。

CSRF(跨站请求伪造)则完全不同——它背叛的是服务器对浏览器的信任。服务器误以为发出的请求都来自经过认证的真实用户,却不知道请求可能是被诱导发出的。攻击者不需要注入任何代码,只需要构造一个恶意链接或表单,利用用户尚未过期的登录状态,让浏览器自动携带Cookie发起请求。这就像有人伪造了你的签名去银行取款,银行柜员看到签名与预留印鉴一致就放行了,根本没意识到签字的人不是你本人。

攻击面与数据流向的差异

维度XSSCSRF
攻击载体恶意脚本(JS/HTML)伪造的HTTP请求
数据流向服务器 → 浏览器(响应)浏览器 → 服务器(请求)
能否读取数据可窃取Cookie、Session等无法直接读取Cookie
防御核心输入过滤 + 输出编码Token验证 + SameSite

从数据流的角度看,XSS是"污染源头",攻击者在响应数据中做手脚,让恶意代码顺着服务器流向用户;CSRF则是"劫持通道",攻击者并不触碰服务器返回的内容,而是逆向利用浏览器的自动提交机制。这也解释了为什么CSRF无法直接窃取用户数据——同源策略会阻止恶意站点读取目标站点的响应内容,但无法阻止目标站点"盲目"执行请求。

防御逻辑的根本分歧

理解了本质区别,防御策略的差异就顺理成章了。防御XSS,核心是净化输出:无论用户输入了什么,在渲染到页面前必须进行HTML实体编码,让浏览器把<script>当成普通文本而非代码执行。Content-Security-Policy(CSP)则是更激进的手段,直接告诉浏览器"只允许加载这些来源的脚本",从根源上切断外部恶意脚本的执行路径。

防御CSRF,关键在于验证来源。服务器不能只依赖Cookie来判断用户身份,必须引入攻击者无法获取的"第二因子"。CSRF Token正是这个角色——它绑定在用户的会话上,每次请求都必须携带,攻击者构造的伪造页面无法跨域读取这个Token值。现代浏览器普遍支持的SameSite Cookie属性则是更优雅的方案:设置为Strict后,Cookie在跨站请求中根本不会被发送,相当于从协议层面封死了CSRF的生存空间。

一个扎心的现实:很多开发者给接口加了CSRF Token防护,却忘了检查XSS漏洞。结果攻击者通过XSS窃取Token,再利用Token发起CSRF攻击——两种攻击链一旦组合,纵深防御形同虚设。

说到底,XSS和CSRF虽然名字里都带着"跨站"二字,但攻击的底层逻辑完全不同。前者是"代码注入",后者是"请求伪造";一个瞄准的是用户浏览器的执行环境,一个瞄准的是服务器的身份验证机制。分清这一点,才能在安全架构设计中做到对症下药,而非头痛医脚。

参与讨论

1 条评论
  • 焦土先知

    这段关于信任链的比喻太贴切了。

    回复