写点什么

安全问题我们需要重视,立刻升级 fastjson2

作者:源字节1号
  • 2023-06-13
    浙江
  • 本文字数:2079 字

    阅读完需:约 7 分钟

安全问题我们需要重视,立刻升级fastjson2

一、前言

小伙伴大家好,我是开源字节快速开发平台的作者。fastjson2.0 是 fastjson 的重要升级,目标是为下一个十年提供一个高性能的 JSON 库,同一套 API 支持 JSON/JSONB 两种协议。

近期 fastjson 再报安全漏洞,直接给我们发送了高危告警,因此升级 fastjson 迫在眉睫。



FasterXML Jackson 是美国 FasterXML 公司的一款适用于 Java 的数据处理工具。Jackson-databind 是其中的一个具有数据绑定功能的组件。Jackson-databind 可以将 Java 对象转换成 json 对象,同样也可以将 json 转换成 Java 对象。

暂且不说 fastjson2 的性能提升,在安全方面也值得我们去升级,这也是我们必须要去做的事。

二、罪魁祸首 AutoType

fastjson、jackson 都支持 AutoType 功能,这个功能在序列化的 JSON 字符串中带上类型信息,在反序列化时,不需要传入类型,实现自动类型识别。

三、fastjson1 安全问题

fastjson 1.x 内部维护了一个白名单,java 发展近 30 年难免有些漏网之鱼,这也造成近几年 fastjson 安全漏洞频发。

四、fastjson2 的设计

  • fastjson2 AutoType 必须显示打开才能使用,没有任何白名单,也不包括任何 Exception 类的白名单。这可以保证缺省配置下是安全的。

序列化时带上类型信息,需要使用 JSONWriter.Feature.WriteClassName。比如:

Bean bean = ...;String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName);
复制代码

很多时候,root 对象是可以知道类型的,里面的对象字段是基类或者不确定类型,这个时候不输出 root 对象的类型信息,可以减少序列化结果的大小,也能提升反序列化的性能。

Bean bean = ...;String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName, JSONWriter.Feature.NotWriteRootClassName);
复制代码

反序列化打开 AutoType 功能支持自动类型

Bean bean = (Bean) JSON.parseObject(jsonString, Object.class, JSONReader.Feature.SupportAutoType);
复制代码
  • fastjson2 AutoType 支持配置 safeMode,在 safeMode 打开后,显式传入 AutoType 参数也不起作用,具体配置如下:

-Dfastjson2.parser.safeMode=true
复制代码
  • fastjson2 AutoType 会经过内置黑名单过滤。该黑名单能拦截大部分常见风险,这个机制不能保证绝对安全,打开 AutoType 不应该在暴露在公网的场景下使用。


五、序列化示例代码

使用 FastJson2JsonRedisSerializer 实现 RedisSerializer 接口

public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>{    public static final Charset DEFAULT_CHARSET    = Charset.forName("UTF-8");    private Class<T> clazz;    public FastJson2JsonRedisSerializer(Class<T> clazz)    {        super();        this.clazz = clazz;    }    @Override    public byte[] serialize(T t) throws SerializationException    {        if (t == null)        {            return new byte[0];        }        return JSON.toJSONString        (t, JSONWriter.Feature.WriteClassName).getBytes        (DEFAULT_CHARSET);    }    @Override    public T deserialize(byte[] bytes) throws SerializationException    {        if (bytes == null || bytes.length <= 0)        {            return null;        }        String str = new String(bytes, DEFAULT_CHARSET);        return JSON.parseObject        (str, clazz, JSONReader.Feature.SupportAutoType);    }}
复制代码

六、升级到 fastjson2

6.1 兼容模式升级

升级可以通过兼容模式升级,兼容模式不需要改代码,但在深度使用的场景,不能做到完全兼容。

  • 兼容模式 Maven 依赖

<dependency>    <groupId>com.alibaba</groupId>    <artifactId>fastjson</artifactId>    <version>${fastjson2.version}</version></dependency>
复制代码

6.2 使用新 API 升级

使用新 API 是建议的升级方式,使用新的 API 能获得更多的功能。

  • 包名编程 FASTJSON v2 和 1.x 版本使用不同的 package,新的 package 名称是 com.alibaba.fastjson2,新 package 和之前不同,可以实现 1.x 和 2.x 共存

import com.alibaba.fastjson2.JSON;import com.alibaba.fastjson2.JSONObject;import com.alibaba.fastjson2.JSONArray;
复制代码
  • Maven 依赖 Maven 依赖的 groupId 和 1.x 不同,使用了新的 groupIdcom.alibaba.fastjson2

<dependency>    <groupId>com.alibaba.fastjson2</groupId>    <artifactId>fastjson2</artifactId>    <version>${fastjson2.version}</version></dependency>
复制代码

我们的项目没有强制依赖 fastjson1,所以选择了直接升级新 API。

最后

fastjson2 在性能和安全上都得到了很好的提升,开源字节开快速开发平台已经完成了升级,代码改动较大,fork 了我们仓库的同学请及时更新,安全无小事,请慎重。


如若转载,请注明出处:开源字节   https://sourcebyte.vip/article/320.html

用户头像

源字节1号

关注

一个着迷于技术又喜欢不断折腾的技术活跃者 2022-03-09 加入

一个着迷于技术又喜欢不断折腾的技术活跃者。喜欢并热爱编程,执着于努力之后所带来的美好生活!

评论

发布
暂无评论
安全问题我们需要重视,立刻升级fastjson2_开源_源字节1号_InfoQ写作社区