前段时间,FastJson被挖出来一个漏洞,可能导致服务直接瘫痪,这个问题就严重,搞的人心惶惶,半夜拼命升级,就怕飞来横锅。
我也是很好奇,一个序列化工具那么大能耐,可以直接把服务弄瘫痪?
本着好奇心,先看下最新版本是怎么修复的,上FastJson的github的官网,找到对应的commiter记录,很好找。
就是它了,点进去可以看到具体的代码差异
原来这个处理方案很暴力,直接加一层过滤,如果字符串包含x,就甩一个异常到你脸上。
那就在本地写一个demo,看看能不能复现,本地用的是1.2.58
设置-Xmx4G,开始运行,过了一两秒,果然甩了我一个OOM
既然复现了,那就debug下哪里出了问题,根据修复代码,我们在JSONLexerbase类的ScanString方法的switch分支中的case 'x' 打个断点。
开始debug,进来之后,进入第一个next方法
next方法会对bp进行+1操作并赋给index,如果index>=this.len(JSON的长度)就会返回'',表示已经读完,否则返回文本内容。
在我们这个例子中,执行完第一个next,index的值已经等于JSON字符串的长度,所以返回了''
执行 charx2=this.next()的时候,index等于9,大于JSON字符串长度,也返回''
继续执行这个case分支的最后一行 this.putChar(x_char)
这个方法中,会对sp和sbuf.length(默认是512)进行比较,如果达到了,就进行扩容,可以猜到这里可能是OOM的元凶,不断的进行扩容,把内存耗尽。
继续往下执行,返回到了scanString方法,在while循环中,执行next方法,因为index值肯定大于JSON字符串长度,所以会返回''
接下去会返回的字符ch,如果是'',会执行 putChar方法(该方法在上面截图中有显示),执行完sp的值+1,然后继续执行,又返回scanString方法,又开始了一轮。
最终sp会涨到512,这个时候,进入if分支,开始扩容。
噩梦就这么开始了...
还没升级到最新版 1.2.60 的小伙伴,抓紧哦。