代码环境
- 仓库:https://github.com/springvortex/spring-cloud-alibaba.git
- 分支:
release/v1.0.0- JDK:
21- Spring Boot:
4.1.0
Redis 缓存里的 JSON 会携带类型信息。如果反序列化允许任意 @type,一旦 Redis 数据被篡改,应用就可能实例化不该实例化的类型。项目的原则是:Redis 不是可信边界。
基础白名单包含:
com.zjc.* 项目内部 DTO
Spring Cache NullValue
java.math.BigDecimal
这次提交把 JDK 类型部分做成配置:
zjc:
cache:
redis:
allowed-sub-types:
- java.math.BigDecimal
装配时会把这些完整类名追加进 BasicPolymorphicTypeValidator:
properties.getAllowedSubTypes()
.forEach(validatorBuilder::allowIfSubType);
默认加入 BigDecimal 是为了让商品金额等数值字段稳定参与多态序列化。后续如果确实需要 BigInteger 之类类型,也通过完整类名显式追加。
这里不建议为了省事放宽到 java.lang.Object 或整个 JDK 包前缀。白名单越宽,安全边界越模糊;测试里专门构造了:
{"@type":"java.lang.Thread"}
并断言反序列化失败,防止未来调整序列化器时把任意类型又放开。
同一次提交还做了几处配套修正:Spring Cloud 版本升到 2025.1.3;业务异常在 Web 日志里降为 WARN,未预期异常仍为 ERROR;商品 Feign 购买契约显式声明 consumes=application/json;购买锁等待调整到 20 秒,库存不足日志降为 INFO。
经验总结
多态缓存方便,但必须显式圈定可反序列化类型。把少量 JDK 类型做成配置化白名单,既保留业务扩展空间,也不把 Redis 当成可信输入。
评论
评论由 GitHub Discussions 承载,需要 GitHub 账号登录。