CVE-2026-24400
Critical · 9.1CVSS
9.1
EPSS
0.6%
Published
Jan 26, 2026
CISA due date
—
Cloudanix analysis
A Java testing library can expose files, trigger unwanted network requests, or crash a process if certain XML helper functions are used on untrusted XML.
- Exploitation
- Local Privilege
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Library
- Class
- XXE
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
AssertJ versions starting at 1.4.0 and before 3.27.7 parse XML in org.assertj.core.util.xml.XmlStringPrettyFormatter.toXmlDocument(String) using DocumentBuilderFactory defaults, which allow DTD processing and external entity resolution. When untrusted XML reaches AbstractCharSequenceAssert.isXmlEqualTo(CharSequence) or XmlStringPrettyFormatter.xmlPrettyFormat(String), an attacker can supply XML with external entities that cause the JVM to read local files through file:// URIs, make outbound HTTP/HTTPS requests for server-side request forgery, or consume CPU and memory through entity expansion attacks such as Billion Laughs. The issue is constrained to code paths that use these AssertJ XML assertion/formatting utilities on attacker-controlled XML; AssertJ is commonly a test dependency, so production impact depends on whether the vulnerable APIs are present in runtime code, CI systems, automated validators, or tools that process untrusted input.
Why it matters to the business
If vulnerable AssertJ XML comparison or formatting code is reachable with untrusted XML, sensitive local files, configuration secrets, credentials, or service metadata may be exposed, internal network services may be probed via SSRF, and affected Java processes may become unavailable due to XML entity expansion. The CVSS score is high, but broad internet-scale exploitation is less likely because the vulnerable functionality is typically in testing code and requires a specific unsafe usage pattern. It is not listed in CISA KEV, is not known to be used in ransomware campaigns, has no reported exploit maturity, and has a low EPSS score, so remediation should be risk-based but still prioritized wherever AssertJ is packaged into production-facing services or automation that handles third-party XML.
How an attack unfolds
An attacker first identifies an application, CI job, testing harness, API validator, plugin, or internal tool that accepts XML and compares or pretty-prints it using AssertJ's isXmlEqualTo(CharSequence) or xmlPrettyFormat(String). The attacker submits crafted XML containing a DOCTYPE declaration and external entity definitions. If the XML parser resolves external entities, the JVM may dereference file:// URIs and embed local file contents into parsed XML or error output, or it may initiate outbound HTTP/HTTPS requests to attacker-controlled or internal endpoints. For denial of service, the attacker submits nested entities that expand exponentially, exhausting memory or CPU during parsing. Successful exploitation depends on the vulnerable AssertJ version being present, the affected APIs being invoked on untrusted XML, and the resulting file contents, network response behavior, or parser errors being observable directly or indirectly.
How to fix it
Upgrade AssertJ to version 3.27.7 or later, or consume a build that includes commit e84071667f5f8f13084af9dfa54cee5fd9db18db. Prefer replacing AbstractCharSequenceAssert.isXmlEqualTo(CharSequence), which was deprecated in AssertJ 3.18.0, with XMLUnit or another XML comparison library configured to disable DTDs and external entity resolution. Remove direct use of org.assertj.core.util.xml.XmlStringPrettyFormatter.xmlPrettyFormat(String) for untrusted input; the utility is deprecated in 3.27.7 and removed in 4.0 with no replacement. Ensure AssertJ is scoped as a test-only dependency where possible and is not included in production runtime artifacts unless required. As a defense-in-depth measure, configure XML parsers to disallow DOCTYPE declarations, disable external general and parameter entities, disable external DTD loading, and enable secure processing. Restrict outbound network access from build agents and application runtimes so SSRF attempts cannot reach internal metadata services or sensitive internal endpoints.
How to confirm the fix worked
Inventory dependencies and confirm no runtime or toolchain component uses org.assertj:assertj-core versions from 1.4.0 through 3.27.6 in code paths that process untrusted XML. Validate package resolution with build tooling such as Maven dependency:tree, Gradle dependencies, SCA output, SBOMs, and runtime artifact inspection. Search source code for isXmlEqualTo(, xmlPrettyFormat(, XmlStringPrettyFormatter, and toXmlDocument(String), then determine whether any call receives user-controlled, third-party, or externally supplied XML. Confirm remediation by verifying AssertJ resolves to 3.27.7 or later, or to a build containing commit e84071667f5f8f13084af9dfa54cee5fd9db18db. Perform a safe negative test in a non-production environment using XML with a benign external entity pointing to a controlled callback URL; a fixed or mitigated implementation should not make the outbound request and should reject or ignore the entity. Also test a small DOCTYPE payload to ensure DTDs are disabled and a controlled entity expansion payload to ensure parser resource limits prevent denial of service.
Typical attack path
- Locate a Java/JVM application, test runner, CI workflow, API contract validator, or developer utility that processes user-supplied XML.
- Confirm or infer that AssertJ versions before 3.27.7 are present and that isXmlEqualTo(CharSequence) or XmlStringPrettyFormatter.xmlPrettyFormat(String) is used on the supplied XML.
- Submit XML containing a DOCTYPE declaration with an external entity referencing a local file, an attacker-controlled HTTP/HTTPS endpoint, or an internal network URL.
- Observe whether the target performs outbound requests, returns XML comparison or formatting errors containing resolved content, or behaves differently based on entity resolution.
- Use file:// entities to attempt local file disclosure, HTTP/HTTPS entities for SSRF and network probing, or recursive entities for denial of service.
- Repeat with targeted file paths, metadata endpoints, or internal service URLs if the vulnerable parsing path is confirmed.
How to detect it
To determine whether exploitation already occurred, review application, CI, build-agent, API gateway, WAF, and reverse-proxy logs for submitted XML containing DOCTYPE, ENTITY, SYSTEM, PUBLIC, file://, http://, https://, or recursive entity patterns. Correlate these requests with Java application logs showing XML parse errors, assertion failures, comparison failures, SAXParseException messages, UnknownHostException, FileNotFoundException, or OutOfMemoryError around the same timestamps. Inspect outbound proxy, firewall, DNS, and EDR telemetry for unexpected network connections initiated by Java processes immediately after XML processing, especially to attacker-controlled domains, internal RFC1918 addresses, localhost, link-local metadata addresses, or unusual high-cardinality DNS names. For file-disclosure attempts, look for payloads referencing common local paths such as /etc/passwd, /etc/hosts, /proc/self/environ, application configuration files, or Windows paths. For denial-of-service attempts, review JVM logs, container events, and monitoring for sudden CPU, heap, garbage-collection, or restart spikes associated with XML parsing. Source and artifact searches for vulnerable API names help identify exposure but are not proof of exploitation.
- <!DOCTYPE
- <!ENTITY
- SYSTEM "file://
- SYSTEM 'file://
- SYSTEM "http://
- SYSTEM 'http://
- SYSTEM "https://
- SYSTEM 'https://
- PUBLIC "-//
- file:///etc/passwd
- file:///etc/hosts
- file:///proc/self/environ
- file:///proc/self/cmdline
- file:///proc/self/cwd
- file:///root/.ssh/id_rsa
- file:///home/
- file:///var/run/secrets/
- file:///var/run/secrets/kubernetes.io/serviceaccount/token
- file:///C:/Windows/win.ini
- file:///C:/Windows/System32/drivers/etc/hosts
- http://169.254.169.254
- http://metadata.google.internal
- http://100.100.100.200
- http://127.0.0.1
- http://localhost
- isXmlEqualTo(
- xmlPrettyFormat(
- XmlStringPrettyFormatter
- org.assertj.core.util.xml.XmlStringPrettyFormatter
- org.assertj.core.api.AbstractCharSequenceAssert
- SAXParseException
- DOCTYPE is disallowed
- External Entity
- entity expansion
- Billion Laughs
- OutOfMemoryError
- java.lang.OutOfMemoryError
- java.net.UnknownHostException
- java.io.FileNotFoundException
What your security team should do
- Prioritize assessment of production services, CI/CD systems, API testing platforms, developer portals, and automation that accept XML from untrusted users or repositories and include AssertJ at runtime.
- Upgrade AssertJ to 3.27.7 or later, or remove AssertJ from production artifacts if it is only needed for tests.
- Replace uses of isXmlEqualTo(CharSequence) with XMLUnit configured with secure XML parsing settings, and eliminate use of XmlStringPrettyFormatter on untrusted XML.
- Add SCA policy to flag AssertJ versions before 3.27.7 and to alert when test libraries are packaged into deployable runtime artifacts.
- Search code for vulnerable API usage and review data flow to determine whether XML input is attacker-controlled.
- Restrict egress from Java services and CI/build agents to reduce SSRF impact, especially access to cloud metadata endpoints and internal administrative services.
- Add logging and monitoring for XML parser errors, DOCTYPE/entity payloads, unexpected outbound requests from Java processes, and resource exhaustion events during XML processing.
- Because the vulnerability is not in KEV, has low EPSS, and has no known public exploit maturity, schedule broad dependency cleanup normally, but expedite remediation for any externally reachable XML-processing path.
The record
AssertJ provides Fluent testing assertions for Java and the Java Virtual Machine (JVM). Starting in version 1.4.0 and prior to version 3.27.7, an XML External Entity (XXE) vulnerability exists in `org.assertj.core.util.xml.XmlStringPrettyFormatter`: the `toXmlDocument(String)` method initializes `DocumentBuilderFactory` with default settings, without disabling DTDs or external entities. This formatter is used by the `isXmlEqualTo(CharSequence)` assertion for `CharSequence` values. An application is vulnerable only when it uses untrusted XML input with either `isXmlEqualTo(CharSequence)` from `org.assertj.core.api.AbstractCharSequenceAssert` or `xmlPrettyFormat(String)` from `org.assertj.core.util.xml.XmlStringPrettyFormatter`. If untrusted XML input is processed by tone of these methods, an attacker couldnread arbitrary local files via `file://` URIs (e.g., `/etc/passwd`, application configuration files); perform Server-Side Request Forgery (SSRF) via HTTP/HTTPS URIs, and/or cause Denial of Service via "Billion Laughs" entity expansion attacks. `isXmlEqualTo(CharSequence)` has been deprecated in favor of XMLUnit in version 3.18.0 and will be removed in version 4.0. Users of affected versions should, in order of preference: replace `isXmlEqualTo(CharSequence)` with XMLUnit, upgrade to version 3.27.7, or avoid using `isXmlEqualTo(CharSequence)` or `XmlStringPrettyFormatter` with untrusted input. `XmlStringPrettyFormatter` has historically been considered a utility for `isXmlEqualTo(CharSequence)` rather than a feature for AssertJ users, so it is deprecated in version 3.27.7 and removed in version 4.0, with no replacement.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| Maven | org.assertj:assertj-core | 1.4.0 | 3.27.7 |
| maven | org.assertj/assertj-core | 1.4.0 | 3.27.7 |
| openSUSE:Leap 15.6 | assertj-core | 0 | 3.27.7-150200.5.9.2 |
| openSUSE:Leap 16.0 | assertj-core | 0 | 3.27.7-160000.1.1 |
| openSUSE:Tumbleweed | assertj-core | 0 | 3.27.7-1.1 |
Related vulnerabilities
- GHSA-rqfh-9r24-8c9r AssertJ has XML External Entity (XXE) vulnerability when parsing untrusted XML via… Same vulnerability
- CVE-2026-89260 MoguBlog through 6.2 contains an XML external entity injection vulnerability in the… CWE-611
- CVE-2026-84941 An information disclosure vulnerability in the SAML Single Sign-On (SSO) functionality of… CWE-611
- CVE-2026-79572 An XXE (XML External Entity) vulnerability in the level-rule module of Distribution… CWE-611
- CVE-2026-19614 The API is prone to XML external entity (XXE) injection. CWE-611
- CVE-2026-71375 Improper restriction of XML external entity reference vulnerability in Cosminexus… CWE-611
- CVE-2026-76958 SAP Integration Suite does not sufficiently validate XML documents accepted from… CWE-611
- CVE-2026-17444 IBM App Connect Enterprise 13.0.1.0 through 13.0.8.1, and 12.0.1.0 through 12.0.12.28 and… CWE-611