geek的技术日志,记录每一次技术思考的闪光点。

fastjson远程代码执行漏洞解决方案

fastjson相信很多人都用过。
近日,网上爆出fastjson存在远程代码执行漏洞!然后我们公司发现好多项目代码都有用到这个包,坑爹了。更坑爹的是老板把这个任务交了给我,要我去研究,负责给出解决方案!本来就很忙的了,NND,还惹上这事。硬着头皮去调研,得出结论如下:

  1. 该bug目前暂未发现对安卓系统造成影响,安卓系统环境可以不用考虑升级。
  2. 建议全部都直接升级为1.2.28最新版。1.2.28已经修复了绝大多数兼容问题。
  3. 如果用了一些非主流的功能(清单见2.2),升级到1.2.28后会出现不兼容情况。

遇到不兼容情况时处理应对方法建议如下:

3.1 参照下表,先回滚到对应的sec01版本,保证系统恢复正常使用。

安全补丁版本升级建议

1.1.15~1.1.31 -> 1.1.31.sec01

1.1.32~1.1.33 -> 1.1.33.sec01

1.1.34 -> 1.1.34.sec01

1.1.35~1.1.46 -> 1.1.46.sec01

1.2.0~1.2.2 -> 1.2.2.sec01 因为1.2.3之后的版本Map是没有排序输出的,如果不关注这个兼容问题,升级到1.2.26

1.2.3~1.2.7 -> 1.2.7.sec01 因为1.2.7使用最多特别提供,也可以直接使用1.2.8.sec01

1.2.8 -> 1.2.8.sec01

1.2.9~1.2.24 -> 1.2.28。

3.2 修复影响兼容的地方。

已知影响兼容的变更

JSONLexer在1.1.32~1.1.34版本中是class,其他版本是interface

JSON#handleResovleTask方法不兼容问题,在 1.1.15返回值是void 1.1.161.1.33版本之前返回类型是int, 1.1.341.1.41版本返回void 1.1.42~1.1.46方法移到JSONParser中

com.alibaba.fastjson.util.Base64/com.alibaba.fastjson.util.ThreadLocalCache类在1.2.9版本被删除

1.2.x中,ObjectSerializer.write方法和ObjectDeserializer

ObjectSerializer/ObjectDeserializer定制序列化,从1.1.x升级到1.2.x会有兼容问题。

打开SerializerFeature.UseISO8601DateFormat时,序列化java.util.Date类型,在1.1.15~1.2.4不带时区,1.2.5及之后版本带时区。

1.2.9~1.2.13版本JSONObject去掉了serialVersionUID字段,会导致Java反序列化不兼容问题

1.2.3之后的版本,Map的序列化没有做排序再输出,原因是通过TreeMap排序很影响性能。1.2.27版本中增加SerializerFeature.MapSortField实现同样的功能。 使用方法如下: a) 传入SerializerFeature.MapSortField参数。 JSON.toJSONString(map, SerializerFeature.MapSortField); b) 通过代码修改全局缺省配置。 JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.MapSortField.getMask(); c) 通过JVM启动参数配置修改全局配置 -Dfastjson.serializerFeatures.MapSortField=true d) 通过类路径下的fastjson.properties来配置 fastjson.serializerFeatures.MapSortField=true

com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter在1.2.10后会在Header中设置ContentLength

1.1.33及之后版本中删除com.alibaba.fastjson.util.AntiCollisionHashMap,会导致Java反序列化不兼容 (1.2.26版本中已经补上)

1.2.10之后的版本,com.alibaba.fastjson.TypeReference去掉了LIST_STRING属性 (1.2.26版本中已经补上)

1.1.21~1.2.25版本中,如果List类型字段配置了JSONField时,parse时不能识别大小写不匹配的情况。 (1.2.26版本中修正)

1.2.11~1.2.25版本中,com.alibaba.fastjson.util.IOUtils类删除了readAll方法。(1.2.26版本中已经补上)

1.2.11~1.2.26版本中,如果输入byte[],并且包含中文字符串的,会有JDK 1.6/1.5不兼容问题。 (1.2.27版本修复)

1.2.9~1.2.26版本中,存在Enum字段类型并且使用了SerializerFilter,序列化时会NoSuchFieldError错误。 (1.2.27版本修复)

1.2.9~1.2.26版本中,会自动识别下划线开头的key,比如:{“id”:1001,”_id”:1002} 这种场景,如果JavaBean中有id字段,最后会得到1002,之前的版本是1001。(在1.2.27版本中修复)

1.2.9之后的版本,对日期格式有严格的校验,”0017-02-12 01:46:17.0″这种格式的日期会报错。

1.2.13之后的版本,{“isSuccess”:}这种字段,能够识别到boolean success字段中,如果isSuccess后的值不规范,会报错。比如{“isSucess”:”Y”}在1.2.12及之前版本是之前版本是会被忽略,1.2.13及之后版本会报错。

1.2.23~1.2.26版本中,如果实际存储和泛型参数不一致的情况,会报错。比如:

public static class Base {
public T id;
}
public static class Model extends Base { }

Model model = new Model();
Base base = model;
base.id = BigInteger.valueOf(3); // 通过Base直接赋值非Long类型, 在1.2.23~1.2.26版本中toJSONString会报错
JSON.toJSONString(base);
问题在1.2.27版本中已经修复

3.3 修复后换回1.2.28最新版,重新上线。

4. 所有升级前先全盘搜索项目代码中是否使用了autotype的功能,如有使用,需要先配置白名单(配置方法见注意事项一栏)。

5. 麻烦运维和QA以后在上线时,对这块把把关,搜索上线项目的pom.xml,检查里面fastjson的版本号是否为1.2.28或者为带sec01的补丁版本号。不符合条件的不给上线。

6.各项目负责人负责更新其负责项目的fastjson包。并尽快安排升级上线。

注意:所有的安全升级包都禁用了部分autotype的功能,也就是”@type”这种指定类型的功能会被限制在一定范围内使用。如果你使用场景中包括了这个功能,请参考附文, 这里有一个介绍如何添加白名单或者打开autotype功能。在1.2.28以及所有的.sec01版本中,有多重保护,但打开autotype之后仍会存在风险,不建议打开,而是使用一个较小范围的白名单。

附文:
autotype的解决方法:
#打开AutoType功能 在1.2.25之后的版本,以及所有的.sec01后缀版本中,autotype功能是受限的,和之前的版本不同,如果在升级的过程中遇到问题,可以通过以下方法配置。

一、添加autotype白名单

添加白名单有三种方式,三选一,如下:

  • 在代码中配置

ParserConfig.getGlobalInstance().addAccept(“com.taobao.pac.client.sdk.dataobject.”);
如果有多个包名前缀,分多次addAccept

  • 加上JVM启动参数-Dfastjson.parser.autoTypeAccept=com.taobao.pac.client.sdk.dataobject.,com.cainiao.
    如果有多个包名前缀,用逗号隔开
  • 通过fastjson.properties文件配置。

在1.2.25/1.2.26版本支持通过类路径的fastjson.properties文件来配置,配置方式如下:

fastjson.parser.autoTypeAccept=com.taobao.pac.client.sdk.dataobject.,com.cainiao. // 如果有多个包名前缀,用逗号隔开

二、打开autotype功能

如果通过配置白名单解决不了问题,可以选择继续打开autotype功能,fastjson在新版本中内置了多重防护,但是还是可能会存在一定风险。两种方法打开autotype,二选一,如下:

1、JVM启动参数

-Dfastjson.parser.autoTypeSupport=true

2、代码中设置

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
如果有使用非全局ParserConfig则用另外调用setAutoTypeSupport(true);

未经允许不得转载:极客技术 » fastjson远程代码执行漏洞解决方案

分享到:更多 ()

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    我们项目用的jackson,因为spring默认依赖的是这个。

    李阳博客6个月前 (03-28)回复