SpringVortexNotes

Redis 多态反序列化白名单要可配置

zjc 于 2026-08-24 发布

代码环境

Redis 缓存里的 JSON 会携带类型信息。如果反序列化允许任意 @type,一旦 Redis 数据被篡改,应用就可能实例化不该实例化的类型。项目的原则是:Redis 不是可信边界。

基础白名单包含:

com.zjc.* 项目内部 DTO
Spring Cache NullValue
java.math.BigDecimal

https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-common/src/main/java/com/zjc/common/cache/RedisCacheAutoConfiguration.java

这次提交把 JDK 类型部分做成配置:

zjc:
  cache:
    redis:
      allowed-sub-types:
        - java.math.BigDecimal

https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-provider/src/main/resources/config/application-redis.yaml

装配时会把这些完整类名追加进 BasicPolymorphicTypeValidator

properties.getAllowedSubTypes()
        .forEach(validatorBuilder::allowIfSubType);

https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-common/src/main/java/com/zjc/common/cache/RedisCacheAutoConfiguration.java

默认加入 BigDecimal 是为了让商品金额等数值字段稳定参与多态序列化。后续如果确实需要 BigInteger 之类类型,也通过完整类名显式追加。

这里不建议为了省事放宽到 java.lang.Object 或整个 JDK 包前缀。白名单越宽,安全边界越模糊;测试里专门构造了:

{"@type":"java.lang.Thread"}

https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-common/src/test/java/com/zjc/common/cache/RedisCacheAutoConfigurationTest.java

并断言反序列化失败,防止未来调整序列化器时把任意类型又放开。

同一次提交还做了几处配套修正:Spring Cloud 版本升到 2025.1.3;业务异常在 Web 日志里降为 WARN,未预期异常仍为 ERROR;商品 Feign 购买契约显式声明 consumes=application/json;购买锁等待调整到 20 秒,库存不足日志降为 INFO。

经验总结

多态缓存方便,但必须显式圈定可反序列化类型。把少量 JDK 类型做成配置化白名单,既保留业务扩展空间,也不把 Redis 当成可信输入。

评论

评论由 GitHub Discussions 承载,需要 GitHub 账号登录。