写在前面的话
早在2008年,Chris Evans就发现了通过在标签中添加恶意参数来跨域窃取Firefox数据的可能性。如果你感兴趣的话,你现在仍然可以阅读当初他所发表的那篇研究报告【传送门】。
他曾在报告中解释称:
现代Web模型对远程网站中标签内的数据没有任何的限制。如果目标远程数据没有必要在标签中出现,那么你可能就会面临着跨域数据泄漏的风险。
整个观点的实现使用了JavaScript错误信息和302重定向,一般来说,现代浏览器会使用类似“Script error”这样的通用信息来替代原本复杂的JavaScript错误信息,并以此来防止网站将错误内容泄露给远程域名。但对于同源网站来说,它们是可以读取到详细的JavaScript错误信息的。
IE浏览器存在同样的问题
通过研究和分析之后,我在IE浏览器上也发现了同样的问题,但是这里有一个特殊的前提条件:加载的页面(具体来说是一个标签页-Tab)必须开启页面的开发者工具(Developers Tools)。
没错,这非常的奇怪,而且开发者工具没有打开的话,我们就无法利用这个漏洞了。除此之外,还有下面这两种限制条件:
(1)必须使用有效的JavaScript变量名;
(2)标签中的数据必须是有效的JavaScript代码;
对攻击者来说,最佳的错误信息形式为“xxxis not defined”,它表示某个名称并没有与任何变量进行绑定,此时你就可以跨域窃取这类单个单词的数据了。但如果跨域数据为CSV,例如“a,b, c”,你仍可以通过遍历的方式窃取到这三部分信息。
因此,只要我们能够满足上面这些前提条件,我们就能够跨域窃取到任何CSV文件的内容。实际上只要满足了上述条件,除了CSV文件之外,几乎任何类型的数据我们都可以窃取到。而且,如果目标页面没有指定字符集(charset)的话,我们还可以使用不同的字符集来窃取数据。如果你对这部分内容感兴趣的话,可以参考Gareth的这篇技术报告【传送门】。
由于ChirsEvan之前给出的PoC已经无法使用了,所以我重新制作了一个PoC。访问地址如下:
http://rootme.in/xssi?url=/redirect%3Furl%3Dhttp%3A%2f%2frequest.rootme.in%2ftoken.csv
感兴趣的同学可以自己动手尝试一下,你可以替换链接中的参数,比方说这样:
http://rootme.in/xssi?url=http://example.com/user_info.js&eval=alert(email)
PoC演示视频
下面是一个15秒的PoC演示视频:
后话
我已经将该问题上报给了微软公司,但由于这项技术的实现前提是开启开发者工具(或提前开启),因此微软方面不认为这是一个非常严重的漏洞,不过他们表示很可能在将来的版本更新中解决这个问题。
下面这个PoC是针对微软Edge浏览器的,如果你感兴趣的话,可以自行查看:
http://blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html
缓解方案
广大开发人员以及网站管理员可以使用下列方法缓解这种安全风险:
1. 使用POST方法;
2. 使用秘密令牌(CSRF);
3. 让URL地址无法预测;
4. 对代码中的引用进行严格审查;
如果数据需要通过ajax请求来获取,那么我们可以参考下面这两种方案:
1. 使用类似for(;
这样的Parser-Breaking语句;
2. 使用自定义的HTTP头;
除此之外,我们也可以通过指定正确的Content-Type头以及X-Content-Type-Options:nosniff来防止这种类型的攻击。但是,对于那些不支持X-Content-Type-Options的浏览器来说,这种方法就不起作用了。
|