FastJson2022年autotype漏洞修复指南 auto type is not support

漏洞说明

为了不浪费时间,直接官方说明 官方链接:

问题

首先说明官方提供给的几种方式中大多是采取禁用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 <T>
 */
 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);

类似这种类型的错都可以试下。 完成后项目正常启动,访问暂时未发现其他问题

结语

经验分享 程序员 微信小程序 职场和发展