当前位置: 首页 > news >正文

Java 集合反序列化漏洞如何修复避免远程代码执行风险

Java 原生序列化机制若直接接收不可信数据,极易引发远程代码执行(RCE)风险。最稳妥的方案是禁止接收不可信数据的反序列化请求,如果业务必须使用,则通过 JDK 自带的序列化过滤机制限制允许的类,并尽快升级存在已知漏洞的第三方依赖库。

先说结论:Java 反序列化漏洞的核心在于攻击者构造恶意对象链,修复重点在于限制可反序列化的类范围。

  • 先判断:确认业务是否真的必须使用 Java 原生序列化接收外部数据,能不用则不用。
  • 优先做:启用 JDK 序列化过滤(JEP 290,需 JDK 8u121+ 或 JDK 9+)或自定义 ObjectInputStream 白名单,同时升级 CommonsCollections 等高危组件。
  • 再验证:使用 ysoserial 工具生成 Payload 验证漏洞是否闭合,并监控线上日志是否有异常类加载。

快速处理思路

如果没有条件立即重构代码,可以通过 JVM 参数或代码层面增加过滤规则。

注意:JVM 参数 -Djdk.serialFilter 仅在 JDK 8u121+ 及 JDK 9+ 版本生效,低版本 JDK 8 必须通过代码修改。

-Djdk.serialFilter=java.lang.String;java.util.ArrayList;com.example.BusinessClass;!*

或者在代码中自定义 ObjectInputStream 的 resolveClass 方法(见下文分步处理)。

为什么会这样

Java 反序列化漏洞通常不是因为序列化机制本身坏了,而是因为在反序列化过程中,JVM 会实例化数据流中指定的类。如果攻击者能找到一条从入口点到危险操作(如执行命令)的“小工具链”(Gadget Chain),就能在反序列化时触发恶意代码。常见的集合类漏洞往往出现在 Apache Commons Collections 等库中,因为它们提供了丰富的方法调用链。

分步处理

1. 排查入口:搜索项目中所有使用 ObjectInputStreamXMLDecoder 或相关框架配置的地方,确认是否有外部数据流入。

2. 实施过滤(JDK 8 代码防御):对于不支持 jdk.serialFilter 的旧版本 JDK,需继承 ObjectInputStream 并重写 resolveClass 方法,建立白名单机制。

public class ValidatingObjectInputStream extends ObjectInputStream {private final List<String> allowedClasses;public ValidatingObjectInputStream(InputStream in, List<String> allowedClasses) throws IOException {super(in);this.allowedClasses = allowedClasses;}@Overrideprotected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {if (!allowedClasses.contains(desc.getName())) {throw new ClassNotFoundException("Deserialization rejected: " + desc.getName());}return super.resolveClass(desc);}
}

3. 升级依赖:检查 Maven 或 Gradle 依赖树,将存在反序列化风险的库升级到安全版本。参考以下常见组件安全版本:

  • Apache Commons Collections:避免使用 3.2.1 及以下版本,推荐升级至 3.2.2+ 或 4.0+。
  • Spring Framework:关注官方安全公告,通常建议升级至最新稳定版。
  • 其他:使用 mvn dependency:tree 排查传递依赖,确保无老旧组件。

4. 替换方案:如果可能,将 Java 原生序列化替换为 JSON 等纯数据格式,避免直接实例化对象。

漏洞复现与验证实操

修复后需验证漏洞是否闭合,推荐使用开源工具 ysoserial 生成 Payload 进行测试。

1. 生成 Payload:下载 ysoserial.jar,使用以下命令生成基于 CommonsCollections5 的 Payload(假设目标命令为 calc.exe):

java -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.bin

2. 发送请求:将生成的 payload.bin 作为请求体发送给目标接口(注意设置 Content-Type 为 application/octet-stream):

curl -X POST `--data-binary` @payload.bin -H "Content-Type: application/octet-stream" http://target-ip:port/vulnerable-api

3. 观察结果:若修复生效,服务端应抛出 ClassNotFoundException 或拒绝反序列化异常,且不会执行计算器程序。同时检查应用日志,确认是否有被过滤类名的拒绝记录。

常见坑

1. 白名单过宽:使用通配符允许了整个包,导致攻击者利用包内其他类构造新链。建议精确到类名。

2. 忽略内部类:静态内部类也需要单独加入白名单,否则反序列化时会失败或被绕过。

3. 框架默认配置:某些框架默认开启反序列化支持,需在配置文件中显式关闭或限制。

4. JDK 版本差异:误以为所有 JDK 8 都支持 jdk.serialFilter,导致在低版本更新号上配置无效。

参考来源

  • Oracle OpenJDK, JEP 290: Serialization Filtering, https://openjdk.org/jeps/290
  • OWASP, Deserialization Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html

原文链接:https://www.zjcp.cc/ask/11772.html

http://www.zskr.cn/news/1349869.html

相关文章:

  • Godot-MCP:编辑器内嵌的AI交互协议栈
  • Godot MCP协议实战:让AI真正理解你的游戏项目
  • Godot-MCP:用自然语言操控编辑器的AI工作流协议
  • 医院病历|基于Java+vue的医院病历管理系统(源码+数据库+文档)
  • 江苏话TTS上线倒计时72小时!ElevenLabs最新v3.2方言引擎实测对比:vs Azure Neural TTS 阿里云SSML方言支持度
  • 渗透测试学习路线:重建系统认知与信任模型
  • 对抗性深度强化学习在自动驾驶可靠性评估中的实践
  • Unity动态障碍物寻路:Recast+Detour实时导航落地实践
  • 掌握Windows Btrfs驱动:在Windows上体验Linux文件系统的强大功能
  • 模型即服务
  • 抖音视频批量下载终极指南:三步搞定高清无水印内容保存
  • 华为交换机VLAN通信原理与Hybrid端口实战配置详解
  • LwIP移植实战指南:从协议栈选型到内存调优的嵌入式网络开发
  • 大连合规有害生物消杀机构排行:资质与实效双维度评测
  • F-P微腔:从多光束干涉原理到光谱成像与传感的现代应用
  • 工业视觉系统设计:从像素当量到光学倍率的参数计算与选型指南
  • TrollInstallerX终极指南:iOS 14-16.6.1设备3分钟一键安装TrollStore
  • Linux LVM 终极实战指南:从 PV/VG/LV 到动态扩容、快照恢复全流程
  • UE中Alembic(ABC)导入原理与生产级管线实践
  • WrenAI:构建智能数据查询的AI代理上下文层终极指南
  • 通过TaotokenCLI工具一键配置多开发环境下的AI模型调用参数
  • 淘金币自动化脚本:5分钟解放双手,淘宝任务全自动执行终极指南
  • iOS自动化测试全链路实战:从WebDriverAgent签名到CI稳定运行
  • 在RISC-V架构芒果派上部署Node.js与EMQX物联网开发环境
  • 嵌入式工程师进阶指南:从C语言到系统架构的30万年薪技能图谱
  • 工业视觉系统精度保障:CCD相机与镜头参数计算实战指南
  • 5个超实用的AI入门技巧,小白也能轻松上手大模型,建议收藏!
  • 终极德州扑克GTO求解器完整指南:从零开始掌握博弈论最优策略的三大突破
  • 3分钟搞定B站缓存:这款神器让视频转换超简单
  • BetterNCM Installer深度解析:网易云音乐插件管理的完整解决方案