持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
背景 针对fastjson最近的反序列化漏洞最近闹得是沸沸扬扬,不出意思,本人所在公司得项目也有这个问题,前几天领导安排我做一下升级。下面的本人的升级过程和方案,供大家参考。
由于Fastjson支持了AutoType能力,所谓的AutoType是对象在进行序列化的时候会将类型抹去,故反序列化时无法获取到原始类型,fastjson为了避免此问题使用了AutoType,即在序列化通过设置SerializerFeature.WriteClassName将序列化的类型记录下来
{
"@type":"com.test.Zoo",
"animal":{
"@type":"com.test.Cat",
"sound":"miao"
},
"name":"cat"
}
后续反序列化时即可得到具体的Cat类型。
引入这一特性虽然带来了方便,但是经常会出现能绕过AutoType黑名单的漏洞问题,阿里为了解决此问题在高版本中增加了safeMode的配置项,启用该配置项将完全禁用AutoType功能,理论上能杜绝此类漏洞的发生。
但完全禁用AutoType能力会给历史已存在的应用带来一定问题,因为如果应用中之前使用了AutoType功能,那么禁用AutoType功能后会无法正常反序列化到具体的类型,而是将直接抛出相关异常,因此需要对此种情况做定制化配置改造。
过程
升级fastjson版本
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
开启safeMode配置
@Configuration
@Data
@EqualsAndHashCode(callSuper = false)
@ConfigurationProperties(prefix="fastjson")
public class FastJsonConfig {
private List<String> autoTypeClass;
@PostConstruct
public void init() {
ParserConfig.getGlobalInstance().setSafeMode(true);
}
}
使用ParserConfig.AutoTypeCheckHandler替代fastjson的AutoType功能
- 添加自定义的类型处理器
@Service
public class FastJsonCheckAutoTypeHandler implements ParserConfig.AutoTypeCheckHandler {
private static final Logger logger = LoggerFactory.getLogger(FastJsonCheckAutoTypeHandler.class);
@Override
public Class<?> handler(String className, Class<?> aClass, int i) {
FastJsonConfig fastJsonConfig = (FastJsonConfig)SpringContextUtil.getBean("fastJsonConfig");
logger.info("Checking autoType className: {}", className);
try {
if (fastJsonConfig.getAutoTypeClass().size()==0) {
return null;
}
List<String> clazzNameArr = fastJsonConfig.getAutoTypeClass();
for (String clazzName : clazzNameArr) {
if (clazzName.equals(className)) {
return Class.forName(className);
}
}
} catch (Exception e) {
logger.error("AutoTypeHandler handle exception!", e);{}", className);
}
return null;
}
}
- 配置需要接管的类 在配置文件中增加名为fastjson.autoTypeClass的配置,将需要使用AutoType的类配置上:
fastjson:
autoTypeClass:
- "com.xxxx.xxx"
- 在需要自动转换的父类指定FastJsonCheckAutoTypeHandler 在父类定义处增加@JSONType(autoTypeCheckHandler = FastJsonCheckAutoTypeHandler.class)配置即可
总结 看到很多项目都只是升级到1.2.83就可以了,但是还是默认开启了AutoType的功能,按照fastjson这个节奏,说不准下次又出什么坑,所以干脆给AutoType禁用掉,使用ParserConfig.AutoTypeCheckHandler接管这个功能就行了,一劳永逸。看似一个小功能,其实里面还是有道道的呀!