浏览器 Web 安全基础系列
CSRF 是怎么冒用登录状态的(当前篇)
CSRF 的关键不是“攻击者偷到了 Cookie”,而是:攻击者让受害者的浏览器替他发送请求,浏览器又自动附带了目标网站的登录 Cookie。

攻击前提
假设用户已经登录银行:
https://bank.example
浏览器保存:
Cookie: sid=abc123
银行有一个只验证登录状态的接口:
app.post('/transfer', requireLogin, (req, res) => {
transfer(req.session.userId, req.body.to, req.body.amount);
res.send('ok');
});
攻击者知道接口地址和参数格式,在自己的网站放置:
<form action="https://bank.example/transfer" method="post">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
</form>
<script>document.forms[0].submit()</script>
用户打开恶意页面后,浏览器向银行提交表单。只要 Cookie 的 SameSite 等规则允许,浏览器就会自动带上银行 Cookie。
银行看到有效 Session,只知道“这个浏览器登录过”,却不知道请求是由恶意页面触发的,于是执行转账。
攻击者通常看不到响应
同源策略和 CORS 通常阻止恶意页面 JavaScript 读取银行响应。但状态修改攻击并不需要读取结果:
删除成功即可
转账成功即可
修改邮箱成功即可
这也是“CORS 报错为什么仍可能造成副作用”的典型场景。

CSRF 常攻击哪些接口
修改邮箱或手机号;
绑定第三方账号;
修改收货地址;
发布或删除内容;
给用户授权;
发起转账或下单;
修改安全设置。
攻击者需要知道接口结构,但不需要知道用户 Cookie 的值。
为什么 GET 不能修改数据
如果删除接口设计成:
GET /delete-account
攻击者只需一张图片:
<img src="https://target.example/delete-account">
浏览器加载图片时就可能触发删除。GET 应当保持安全、幂等语义,不用于修改服务器状态。
但把 GET 改成 POST 仍不等于防住 CSRF,因为 HTML 表单可以提交 POST。
为什么 HttpOnly 不防 CSRF
HttpOnly 只阻止 JavaScript 读取 Cookie:
document.cookie // 看不到 sid
CSRF 根本不需要读取 sid;浏览器会在请求时自动携带。因此 HttpOnly 很重要,但它解决的是 Cookie 被脚本直接窃取的问题。
为什么 Authorization 请求头风险不同
如果 Token 保存在内存中,并由前端主动写入:
fetch('/api/transfer', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` }
});
攻击者的普通表单无法自动添加这个请求头,传统 CSRF 风险明显下降。但 XSS 一旦能读取或使用 Token,仍然危险;Token 存储、刷新和撤销也有其他权衡。
本地实验观察点
完整实验位于:
examples/06-csrf-attack/
它启动:
受害网站
http://localhost:3060;恶意网站
http://localhost:4060。
实验步骤:
在受害网站登录,余额为 10000。
打开恶意网站并点击“领取奖励”。
恶意页面自动向受害网站提交转账表单。
回到受害网站,余额减少。
在开发者工具 Network 中查看请求的
Origin、Cookie和 Form Data。
同一主机不同端口是跨源但同站,因此实验能帮助观察:CORS 和 SameSite 判断的边界并不相同。
CSRF 成立条件
可以用四个问题快速判断:
用户是否已经在目标网站建立登录状态?
身份凭证是否会被浏览器自动附带?
攻击者能否构造目标接口接受的请求格式?
服务端是否只验证登录,而没有验证请求来源或随机 Token?
条件越齐全,风险越高。
常见误区
攻击者必须跨域读取 Cookie
不需要。攻击者依赖浏览器自动携带。
POST 天生安全
不对。普通 HTML 表单可以跨源 POST。
JSON 接口一定没有 CSRF
如果接口只接受带自定义头的 JSON,普通表单难以构造,但仍应检查 CORS、内容类型处理、同站攻击和认证方式,不能只靠“目前表单发不了 JSON”。
小结
CSRF 是“借身份执行”,不是“偷身份凭证”。浏览器自动携带认证 Cookie,服务端又无法仅凭 Cookie 判断操作意图,因此需要 SameSite、CSRF Token、Origin/Referer 校验等多层防护。
参考资料
CSRF 是怎么冒用登录状态的:攻击原理与本地实验
https://lautung.com/archives/web-security-06-csrf-attack
评论