OSChina XSS 漏洞发现 | OSChina XSS Vulnerability

好吧,最近着迷XSS问题了,国产软件XSS漏洞真多。闲得无聊之中,上OSChina准备发日志,后来发现日志允许插入音乐,而音乐的地址是嵌入在一段JS里面的。想到了没有?XSS可能性啊! 于是这是KnH.C 发现的第二个XSS 0day漏洞了。

It has just been discovered that OSChina.net has a potential XSS exploit hole, users may introduce code not originally inside the website JS. Although users may not add code to their liking, the hole is fairly wide as it allows arbitary but limited length JavaScript injection. Using the DOM model, it is possible to inject HTML code as well. All browsers are affected.

以下是漏洞报告 / Below is a full disclosure of the bug :

特别提醒:使用网络应用程序的漏洞进行破坏性行为是可耻也是违背法律的,请读者本着学习的态度阅读此文,虽然是0day漏洞,但是请克制自己尝试的欲望。

好吧,这次轮到OSChina出问题了,其实本来挺难出现这个问题的,但是在发日志的过程之中无意发现居然可以嵌入mp3? 那么怎么嵌入的呢?于是我发了一个测试用的日志来嵌入MP3,得到了这样的结果。

<script type='text/javascript'>
      var so = new SWFObject('/js/mp3-player.swf','mpl','470','24','9');
      so.addParam('allowfullscreen','true');
      so.addParam('allowscriptaccess','always');
      so.addParam('wmode','opaque');
      so.addVariable('file','http://HERE_IS_MP3_URL');
      so.addVariable('autostart','true');
      so.addVariable('repeat','none');
      so.write('mediaspace');
</script>

看起来挺无害的?那就错了。OSChina对MP3文件URL是有校验的,不合格的URL不允许加入,不过后来发现校验很不足,貌似仅仅不允许“ ”空格出现在URL里面…实在是悲剧。好吧,咱们分析问题:常理下 URL在这里不会出什么大乱子,但是OSChina在这里犯了一个严重的错误:没有ESCAPE掉URL里面的特殊字符。
假设URL如下

http://noexist/a.mp3');alert('hello_world

会如何呢?于是发了一个日志使用了这个URL作为背景音乐地址。得到了这个结果:

<script type='text/javascript'>
      var so = new SWFObject('/js/mp3-player.swf','mpl','470','24','9');
      so.addParam('allowfullscreen','true');
      so.addParam('allowscriptaccess','always');
      so.addParam('wmode','opaque');
      so.addVariable('file','http://noexist/a.mp3');alert('hello_world');
      so.addVariable('autostart','true');
      so.addVariable('repeat','none');
      so.write('mediaspace');
</script>

啊啦,问题严重了。

这个漏洞的严重性在于不和谐用户可以通过写入DOM来引入外来脚本,动态添加JS,从而达到XSS目的。而且,如果MP3是合法存在的地址,可以把攻击做得悄无声息。

成功利用漏洞的脚本可以在用户登陆或未登陆的情况下进行代码执行,诱导浏览器操作等严重安全隐患。一个制作巧妙的博客文章可能欺骗用户点击进而出现不可预测的问题。

在此提醒:URL域是很危险的,特别是当URL中的特殊字符不被过滤的时候。这时最好的办法是 urlencode() 一下地址再记入数据库。同时,在JS里面输出字符串,应该把引号给转义。比如单引号输出,那么应该把字符串里的 ‘ 都转义为 \’ 。

OSChina是个很不错的网站,希望网站方能尽快修复这个问题!谢谢。KnH网络安全社还会继续关注网络的潜在不安全问题,希望这对所有处理URL的应用是个警戒。

漏洞已报告OSChina站长,目前等待修复。

UPDATE:修复尝试 #1是失败的,请OSChina站长注意,您不仅需要替换 ‘ 为 &apos;,建议直接把 URL过一下类似 urlencode()的函数。比如下面代码还是可以用:

http://noexist/a.mp3</script><script>alert("hello_world");</script>

依然可用,最好把 < 编码 &lt;

UPDATE 2: 目前该漏洞已经修复完毕!谢谢关注!

24 Comments

    1. 对,这是有道理的。不过其实原来都用HTML注释包裹JS代码,这样自然解决了里面有script字段的问题了,不过现在直接把JS代码写在2个script标签内,其实是不规范的(或者说不提倡的)。但是大家都那样做,浏览器也不抱怨只能把优先级提高。
      PHP的话如果出现PHP标签在引号内倒是不会因此退出。

      回复

  1. 我觉得这个问题常见是因为数据作为HTML编码有HTMLencode,作为地址编码有URLencode,但是作为java变量编码缺少缺省函数。其实编码方式类似于反SQL注入,就是替换引号。

    回复

    1. 对,主要没有过滤HTML ENTITIES,但是这里需要Url Encode一下,如果仅仅转义银号,由于 <script> 标签比 ‘ 级别高,所以只要地址插入然后就可以切断JS代码块,也是不行的。必须把 < 变成 &lt;

      回复

        1. PS 你知道我的站点也有XSS漏洞,有一部分代码是我自己编的,后来自己想到了可能出现问题,不过一直懒得改了(反正也没人发现),你看看你能不能猜出来是哪里。(本站没用到AJAX所以肯定不是那里的问题)。

          回复

            1. 对,你可以研究研究怎么实现。很有意思。最近BHSF网络安全社正在招募新一届BHSFer接班(而且一堆牛人,特别是WP China那位),这个作为一个入门测试,找到的就直接录取^_^。你也可以玩玩。漏洞倒不是故意写的,就是发现后忘了修正而已。

              回复

发表回复

您的电子邮箱地址不会被公开。