fastjson漏洞导致服务瘫痪,先别忙升级

1、背景
  2019年9月5日,fastjson修复了当字符串中包含\x转义字符时可能引发OOM的问题。建议广大用户升级fastjson版本至少到1.2.60。
  一个bug这么恐怖,竟然直接OOM,亲身体验下吧。测试代码如下:

JSON.parse("[{\"a\":\"a\\x]");
实验效果:4分钟 堆内存 占用上升达2G;

fastjson_x_oom

  这么牛掰,甲方爸爸高度重视,火速把自己负责的服务的fastjson版本升级到1.2.60,线上运行也相安无事。

  如果这就结束了,本文也就不用写了。⊙﹏⊙‖∣

2、fastjson升级后业务异常
  fastjson升级几天后,一老系统业务发生异常,异常信息如下:

Exception in thread "xxx" com.alibaba.fastjson.JSONException:www.lanxingylgw.cn expect ‘:‘ at 0, actual =
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:290)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(www.fengmingpt.com DefaultJSONParser.java:1380)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(www.jujinyule.com DefaultJSONParser.java:1346)
at com.alibaba.fastjson.JSON.parse(www.hjhyLe.com JSON.java:156)
at com.alibaba.fastjson.JSON.parse(www.shicaiyl.com JSON.java:166)
at com.alibaba.fastjson.JSON.parse(JSON.java:135)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:227)
at alibaba.fastjson.FastJsonBug.main(FastJsonBug.java:70)
www.jintianxuesha.com/?cate=2
  看这错误,肯定是json字符串格式有误,应该是冒号的地方实际上是等号了,然后导致反序列化异常,果断排查接口入参,结果入参一切正常。纳尼。。。
  好吧,那就本地debug吧,结果竟然在本地复现异常了,震惊!!!再次检查接口入参,没有问题,和以前正常运行的入参是一致的。想到最近升级fastjson了,还原fastjson版本试试吧。还原后还真是正常了!!!

  难道fastjson版本升级出了大bug?

黑人问号

  本着对阿里技术的信任,我决定一探究竟。

3、一探究竟
  待反序列化的数据,其格式是2层List嵌套,测试代码已做脱敏处理(完整源码见后文github地址):

String json = "{\"bvos\":[{\"names\"www.zeshengyule.com:[\"zxiaofan\"]}]}";
JSONObject jsonObjectB1 = GSON.fromJson(json, JSONObject.class);
JSONArray jsonArrayB = jsonObjectB1.getJSONArray("bvos");
JSONObject jsonObjectB2 = JSONObject.parseObject(jsonArrayB.get(0).toString());
// 上面这行代码直接异常了,异常信息如下:
// com.alibaba.fastjson.JSONException: expect ‘:‘ at 0, actual =
  好奇宝宝们就不要纠结于为什么没有定义好实体再使用TypeReference一步到位啦,千年老代码确实是这样的,这也不是本文的重点。
  经过debug发现,jsonArrayB.get(0).toString()的值是 {names=[zxiaofan]}。注意了,names后面是等号,不是冒号,这也就能解释为什么异常是“expect ‘:‘ at 0, actual =”了。
  但为什么升级后就异常,没升级就一切正常呢?继续研究下,梳理后发现如下值得注意的地方:

1、fastjson版本时1.2.54时正常,大于1.2.54后便会异常;
2、运行代码是Google的Gson和阿里的fastjson混用的(json处理全部换成fastjson一切正常);
  莫非,是fastjson升级后和Google的Gson不兼容导致?

仿佛看到了曙光。

看到了曙光

  对比分析了fastjson 1.2.54版本和其之后的版本(以下以1.2.55版本为例),发现getJSONArray(String key)还真有区别。

// fastjson <version>1.2.54</version>

public JSONArray getJSONArray(String key) {
Object value = this.map.get(key);
if (value instanceof JSONArray) {
return (JSONArray)value;
} else {
return value instanceof String www.feihongyul.cn (JSONArray)JSON.parse((String)value) : (JSONArray)toJSON(value);
}
}
// fastjson <version>1.2.55</version>

public JSONArray getJSONArray(String key) {
Object value = this.map.get(key);
if (value instanceof JSONArray) {
return (JSONArray)value;
} else if (value instanceof List) {
return new JSONArray(www.haojuylpt.com (List)value);
} else {
return value instanceof String ? (JSONArray)JSON.parse((String)value) : (JSONArray)toJSON(value);
}
}
  经过调试后发现,1.2.54版本在getJSONArray(String key)方法中使用的是(JSONArray)toJSON(value),而1.2.55版本在getJSONArray(String key)方法中使用的是return new JSONArray((List)value)。两者处理后返回的数据也确实不同。

fastjson 1.2.54 版本:

fastjson 1.2.54 版本

fastjson 1.2.55 版本:

fastjson 1.2.55 版本

  从调试情况看,1.2.54版本最终返回的是JSONObect,1.2.55版本返回的是LinkedTreeMap。Map结构toString()的结构肯定是“key=value”,而不是json结构。
  但是如果将测试代码中的GSON.fromJson替换成JSON.parseObject,那么不论fastjson的版本高低,都能正常运行。

  至此,我们知道了,fastjson在升级到1.2.55及以上版本后,getJSONArray方法对Google的Gson处理后的数据兼容性降低,或许本文的名字叫做《fastjson与Gson混用引发的bug》更合适。
  也不知道这算不算是bug,给官方提了个issue: > fastjson版本升级降低了对Gson的兼容性 #2814。

4、学习下fastjson对各种数据类型的处理
  在分析的过程中,看了fastjson中getJSONArray方法对各种数据类型的处理方式,和自己以前写的类似代码相比fastjson的代码更优雅,值得学习。相关方法com.alibaba.fastjson.JSON.toJSON(),有兴趣的同学可以看看。

// 此处代码仅展示核心结构,如需查阅完整代码请前往github/fastjson查看。
// toJSON简直是 数据类型分类处理的模板。@zxiaofan
@SuppressWarnings("unchecked")
public static Object toJSON(Object javaObject, SerializeConfig config) {
if (javaObject == null) {
return null;
}
if (javaObject instanceof JSON) {
return javaObject;
}
if (javaObject instanceof Map) {
if (map instanceof LinkedHashMap) {
} else if (map instanceof TreeMap) {
} else {
innerMap = new HashMap(www.xingxinyulzc.cn size);
}
return json;
}

if (javaObject instanceof Collection) {
for (Object item : collection) {
}
return array;
}

if (javaObject instanceof JSONSerializable) {
return JSON.parse(json);
}

Class<!--?--> clazz = javaObject.getClass();

if (clazz.isEnum()) {
return ((Enum<!--?-->) javaObject).name();
}

if (clazz.isArray()) {
for (int i = 0; i &lt; len; ++i) {
}
return array;
}

if (ParserConfig.isPrimitive2(clazz)) {
return javaObject;
}
ObjectSerializer serializer = config.getObjectWriter(clazz);
if (serializer instanceof JavaBeanSerializer) {
return json;
}
String text = JSON.toJSONString(javaObject);
return JSON.parse(text);
}
5、总结
正如文中总结,fastjson在升级到1.2.55及以上版本后,getJSONArray方法对Google的Gson处理后的数据兼容性降低,或许本文的名字叫做《fastjson与Gson混用引发的bug》更合适。
代码规范:同一模块代码不允许混用Json解析工具;
保持敬畏:生产发布,一定要保持敬畏,对变更充分回归;
问题很简单,重要的是思考方式,在寻找答案的过程中学到更多。
> 敬畏生命,敬畏职责,敬畏规章。
当你认为没有错误的时候,错误一定会来找你。
--《中国机长》

原文地址:https://www.cnblogs.com/dakunqq/p/11669002.html

时间: 2024-11-13 06:57:42

fastjson漏洞导致服务瘫痪,先别忙升级的相关文章

APP漏洞导致移动支付隐患重重,未来之路如何走?

没有一种支付是100%安全的,互联网及移动支付规模的增长,其交易的安全性需要银行.支付公司.App开发者.用户等参与各方更加重视.当下手机支付似乎变成了一种时尚,用户们"刷手机"乘地铁,"刷手机"购物,"刷手机"喝咖啡,"刷手机"看电影,甚至"刷手机"定机票--种种迹象表明手机支付已经迎来了一个高速发展期. 移动支付行业隐患重重,未来发展道路令人堪忧 但随着移动支付业务金额的疯狂涨势,移动支付背后的隐患也让

XSS攻击:SOHU视频XSS漏洞导致其用户成为DDOS肉鸡

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的. from:http://www.incapsula.com/blog/world-largest-site-xss-ddos-zombies.html incapsula发现其一个客户遭受了应用层的DDos攻击. 大概有22000的互联网用户对其网站发起了2000万的GET请求. 

解决ArcGIS中因SDE或数据库配置问题而导致服务荡掉的一种思路

1.背景 最近连续有两个项目现场出现了AGS服务荡掉的问题,一个是通州现场,一个是福州现场. 1.1通州现场的问题描述和解决思路 通州现场环境为ArcGIS9.2,使用IMS发布的地图服务,其问题表现为每隔两天左右,其地形图服务便会崩溃一次,重启地形图服务后地图可以正常显示. 因为IMS中地图的出图为动态出图,所以其出图时需要通过连接SDE,此问题的出现很可能是SDE中最大连接数的问题. 1.2福州现场的问题描述和解决思路 福州现场环境为ArcGIS10.0,使用的ArcGIS Server发布

少部分手机浏览器对于COOKIE支持不够导致服务端无法读取session的解决方案

相信大家都遇到过这样的问题,有手机浏览器的问题导致服务端SESSION读取不正常,目前在项目中的解决方法是采取H5手机本地存储唯一KEY解决的 代码片段 //定义json格式字符串 var userData = { name: "sankyu Name", account:"sankyu", level:1. disabled:true }; //存储userData数据 localStorage.setItem("userData",JSON.

WebLogic反序列化漏洞导致getshell

本文主要是讲述在主机渗透中我们经常使用的一条路径(存活判断-端口扫描-端口删选(web端口)-针对性渗透(web渗透))进行渗透,其中主要涉及发现漏洞.利用漏洞.获取上传位置等过程中自己的一点经验技巧.简单来说,本文主要是对某主机进行渗透的全过程记录!如有不合理或错误的地方,烦请各位多多指教,谢谢! 1.1    主机存活判断 当我们得到一个主机IP时,我们首先对它进行存活判断,最简单的就是通过ping命令,但是如果主机是禁ping那么我们可能会判断失误,因此我们需要使用nmap来再次进行存活判

jenkins日志异常增大导致服务不可用的处理过程

今天发现mysql服务报28错误(28错误是磁盘空间不足导致),查看服务器的磁盘空间使用情况,发现tomcat目录下的日志文件catalina.out异常,报错如下: question:      [[email protected] type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]        question:      [[email protected] type: TYPE_IGNORE index 0,

Hadoop--SecondNameNode导致服务启动时间超长

最近遇到个问题,每次重启Hadoop发现HDFS控制台都无法访问,并且查看nameNode的JOBTracker日志,如下 2015-02-05 09:36:18,935 ERROR org.apache.hadoop.security.UserGroupInformation: PriviledgedActionException as:hadoop cause:java.net.ConnectException: Call to haier002/10.255.254.3:9099 fail

测试服务挂了导致服务不可用的排除方法及重启服务的分享

在测试过程中,经常遇到接口报502错误,导致测试阻滞,初步排查服务及重启服务的方法如下: 举例抓包中遇到如下报错 初步断定是服务问题,可能是服务挂了,导致访问报502,这里我们要去找这个服务部署在哪台服务器上,哪个项目里,我们可以先进入http://www.sqaproxy.com/ 查找这个域名对应的服务器 该域名对应的是10.168.105.33:10012 进入这台服务器,对应的tomcat目录内 通过端口,可以知道dfc-test.sqaproxy.com服务是部署在apache-tom

Confluence 目录穿越漏洞导致代码执行CVE-2019-3398

0x00 漏洞详情 Confluence Server和Data Center产品在downloadallattachments资源中存在一个路径穿越漏洞.有权向页面和(或)博客添加附件,或创建新空间或个人空间,或者对空间具有"管理员"权限的远程***者可以利用此漏洞将文件写入任意位置,最终导致远程代码执行. 0x01 影响范围 0x02 修复建议 升级Confluence Server或Data Center版本:6.6.136.13.46.14.36.15.2执行官方缓解措施:停止