Java反序列化漏洞本质是将不可信字节流当作可信对象还原,触发攻击者预埋代码;防御需切断恶意数据入口、强制白名单过滤(如ObjectInputFilter)、禁用不可信源readObject()、替换为JSON等安全格式,并升级加固高危依赖库。

Java反序列化漏洞的本质,是把不可信的字节流当作可信对象来还原,结果在重建过程中触发了攻击者预埋的代码执行逻辑。防御的关键不是“堵住某个类”,而是从源头切断恶意数据进入反序列化流程的路径,并限制其执行能力。
只对完全可信的数据调用 readObject()
检查项目中每一处 ObjectInputStream.readObject() 的调用点:
- 输入是否来自内部系统直连(如同一JVM内传参、本地文件且由你完全控制)
- 是否来自HTTP请求体、消息队列、前端表单、上传文件、外部API响应等不可控来源——这些一律禁用原生反序列化
- 特别注意RMI、JMX、Shiro RememberMe、WebLogic T3协议等隐式触发点,它们可能在你没写
readObject()的情况下自动反序列化
强制启用白名单过滤(推荐 Java 9+)
使用 ObjectInputFilter 在反序列化前拦截并校验类名,这是目前最直接有效的机制:
- 定义允许范围,例如:
"com.myapp.dto.*;maxdepth=5;maxrefs=1000" - 设置方式:在创建
ObjectInputStream后立即调用setObjectInputFilter() - 不要依赖黑名单(如禁止
Runtime),绕过方式极多;白名单才是根本解法
用安全格式替代 Java 原生序列化
除非有强兼容性要求,否则应主动弃用 Serializable 接口:
- 传输场景优先选 JSON(Jackson/Gson),它只解析数据,不执行任意方法
- 高性能或跨语言场景可用 Protocol Buffers 或 Avro,二者均无动态类加载风险
- 若必须用 XML,禁用外部实体(
XMLInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false))
加固第三方组件与依赖库
很多漏洞并非你写的代码导致,而是引入了带 gadget 链的老版本库:
- Apache Commons Collections 升级到 4.1+,或彻底移除不用
- Fastjson 启用
safeMode=true,或迁移到 Jackson - Jackson-databind 禁用
enableDefaultTyping(),升级至已修复版本 - 定期扫描依赖树,关注 CVE 报告中涉及
commons-collections、c3p0、groovy等高危库的更新
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











