FastJson漏洞,瞬间让你的服务瘫痪!根因分析

前段时间,FastJson被挖出来一个漏洞,可能导致服务直接瘫痪,这个问题就严重,搞的人心惶惶,半夜拼命升级,就怕飞来横锅。

我也是很好奇,一个序列化工具那么大能耐,可以直接把服务弄瘫痪?

本着好奇心,先看下最新版本是怎么修复的,上FastJson的github的官网,找到对应的commiter记录,很好找。

就是它了,点进去可以看到具体的代码差异

原来这个处理方案很暴力,直接加一层过滤,如果字符串包含\x,就甩一个异常到你脸上。

那就在本地写一个demo,看看能不能复现,本地用的是1.2.58

  1. publicclassFastJsonCase{
  2. publicstaticvoid main(String[] args){
  3. //{"a":"\\x
  4. //是由于fastjson处理字符串中\\x这种HEX字符表示形式出现的问题。
  5. String DEATH_STRING ="{\"a\":\"\\x";//输入字符串长度为8
  6. try{
  7. Object obj = JSON.parse(DEATH_STRING);
  8. System.out.println(obj);
  9. }catch(JSONException ex){
  10. System.out.println(ex);
  11. }
  12. }
  13. }

设置-Xmx4G,开始运行,过了一两秒,果然甩了我一个OOM

既然复现了,那就debug下哪里出了问题,根据修复代码,我们在JSONLexerbase类的ScanString方法的switch分支中的case ‘x’ 打个断点。

开始debug,进来之后,进入第一个next方法

next方法会对bp进行+1操作并赋给index,如果index>=this.len(JSON的长度)就会返回’\u001A’,表示已经读完,否则返回文本内容。

在我们这个例子中,执行完第一个next,index的值已经等于JSON字符串的长度,所以返回了’\u001A’

执行 charx2=this.next()的时候,index等于9,大于JSON字符串长度,也返回’\u001A’

继续执行这个case分支的最后一行 this.putChar(x_char)

这个方法中,会对sp和sbuf.length(默认是512)进行比较,如果达到了,就进行扩容,可以猜到这里可能是OOM的元凶,不断的进行扩容,把内存耗尽。

继续往下执行,返回到了scanString方法,在while循环中,执行next方法,因为index值肯定大于JSON字符串长度,所以会返回’\u001A’

接下去会返回的字符ch,如果是’\u001A’,会执行 putChar方法(该方法在上面截图中有显示),执行完sp的值+1,然后继续执行,又返回scanString方法,又开始了一轮。

最终sp会涨到512,这个时候,进入if分支,开始扩容。

噩梦就这么开始了…

还没升级到最新版 1.2.60 的小伙伴,抓紧哦。

本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
极客文库 » FastJson漏洞,瞬间让你的服务瘫痪!根因分析

Leave a Reply

欢迎加入「极客文库」,成为原创作者从这里开始!

立即加入 了解更多