核心是阻断不可信数据进入objectinputstream.readobject()。需禁用web层直接反序列化、关闭rmi/jms默认绑定、改用json存储session、强制白名单过滤(java 9+ objectinputfilter)、清理危险依赖、网关拦截魔数aced0005、apm监控调用栈并沙箱隔离。
核心是不让不可信数据走到 objectinputstream.readobject() 这一步。java 原生反序列化机制本身不校验类合法性,一旦攻击者控制输入流,就能通过 gadget 链触发 runtime.exec、jndi lookup 等高危操作,直接导致全站 rce。
只对可信来源执行反序列化
外部输入一律视为不可信——HTTP 请求体、文件上传、消息队列、Redis 缓存、日志字段、调试接口参数等,都不能直接喂给 ObjectInputStream。
- Web 层禁用
request.getInputStream() + ObjectInputStream解析用户提交内容 - RMI、JMS 等中间件通信中,关闭默认的
UnicastRemoteObject绑定,避免暴露反序列化入口 - Session 存储若用 Java 序列化(如 Tomcat 默认),应切换为 JSON 或加密字符串格式
强制启用类名白名单机制
不依赖黑名单(易漏、难维护),必须采用白名单精确放行。优先使用 Java 9+ 的 ObjectInputFilter,或自定义安全子类。
- 全局设置(推荐 Java 11+):
ObjectInputFilter.Config.setSerialFilter(filter),只允许com.mycompany.dto.**类型 - 局部控制:创建
ObjectInputStream后立即调用setObjectInputFilter(),绑定当前业务所需类范围 - 兼容旧版本:继承
ObjectInputStream,重写resolveClass(),对desc.getName()做包路径前缀匹配
切断常见 gadget 链依赖
很多 RCE 是靠第三方库中的危险类组合触发的,必须从依赖层面主动清理和加固。
- 升级关键组件:Commons Collections ≥ 4.1,Jackson-databind ≥ 2.15.2,Log4j ≥ 2.20.0
- 禁用高危反射能力:JVM 启动参数添加
-Dorg.apache.commons.collections.enableUnsafeSerialization=false - 移除非必要依赖:groovy、commons-beanutils、ysoserial 测试包、旧版 c3p0 等一律剔除
运行时监控与纵深防护
代码层防御可能遗漏,需在生产环境叠加检测能力,做到“防不住也要能发现”。
- 网关层拦截:Spring Cloud Gateway 或 WAF 规则识别 Java 序列化魔数
AC ED 00 05,直接拒绝含该字节序列的 POST/PUT 请求 - APM 监控:集成 Contrast Security 或 OpenTelemetry,对
ObjectInputStream.readObject()调用栈做高频告警 - 沙箱隔离:将必须保留的反序列化逻辑放入低权限容器或 SecurityManager 沙箱中运行,限制其调用
exec、openConnection等敏感 API











