FastJson2022年autotype漏洞修复指南
FastJson2022年autotype漏洞修复指南
- 漏洞说明
- 问题
-
- 1.产生问题的代码
- 不兜圈子,直接说明升级及解决方案
- 结语
漏洞说明
为了不浪费时间,直接官方说明
官方链接: link
问题
首先说明官方提供给的几种方式中大多是采取禁用autoType这个功能。
但是这个对于业务中使用了autotype功能且已经上线的应用非常不友好,直接使用最新版本fastjson或者开启safemode都会直接导致原有应用报错。下面介绍我司应用升级采取的修改,各位可参考
1.产生问题的代码
在使用fastjson 代理redis的template模板时开启了autotype
@SuppressWarnings("all") @Bean(name = "redisTemplate") @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); //序列化 FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); // value值的序列化采用fastJsonRedisSerializer template.setValueSerializer(fastJsonRedisSerializer); template.setHashValueSerializer(fastJsonRedisSerializer); // 全局开启AutoType,这里方便开发,使用全局的方式 ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // 建议使用这种方式,小范围指定白名单// ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain"); // key的序列化采用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; }
在使用fastjson进行序列化和反序列化时使用了SerializerFeature.WriteClassName,因此产生了@type类型的漏洞
/** * Value 序列化 * * @author / * @param */ class FastJsonRedisSerializer<T> implements RedisSerializer<T> { private final Class<T> clazz; FastJsonRedisSerializer(Class<T> clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) { if (t == null) { return new byte[0]; } //!!!!问题所在 return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8); } @Override public T deserialize(byte[] bytes) { if (bytes == null || bytes.length <= 0) { return null; } String str = new String(bytes, StandardCharsets.UTF_8); return JSON.parseObject(str, clazz); }}
不兜圈子,直接说明升级及解决方案
首先升级fastjson,我司版本由1.2.70>1.2.83
什么配置都不动,启动项目登陆后报错
报错是这样的:
auto type is not support : security
此处直接贴解决方案:redisConfig的redisTemplate中添加白名单
// 全局开启AutoType,这里方便开发,使用全局的方式 ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // 建议使用这种方式,小范围指定白名单// ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain"); ParserConfig.getGlobalInstance().addAccept("org.springframework.security.core.authority."); TypeUtils.addMapping("org.springframework.security.core.authority.SimpleGrantedAuthority", SimpleGrantedAuthority.class);
类似这种类型的错都可以试下。
完成后项目正常启动,访问暂时未发现其他问题
结语
首先这种改法会不会造成漏洞放开还是未知,毕竟至今作者也没有公布漏洞的利用条件。但我相信作者将security放入黑名单肯定是有一定目的的。
其次,如今升级后普遍反映时间反序列化后丢失分秒,这个问题暂时未碰到。后续测试观望。