AssertJ is one of the most popular libraries for fluent assertions in Java testing. While it makes tests expressive and readable, a serious XML External Entity (XXE) vulnerability—CVE-2026-24400—impacts all versions from 1.4. up to, but not including, 3.27.7. This post gives you a detailed—but simple—explanation of the issue, shows how exploitation works, and outlines steps to secure your code.
What is the Vulnerability?
The problem is with the internal XmlStringPrettyFormatter utility, specifically its toXmlDocument(String) method. The method parses XML input like this:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
What's wrong?
The factory is initialized with *default settings*; it doesn't disable external entity resolution or prevent DTDs. That means, if untrusted XML is given to the method (or to its wrapper assertion methods like isXmlEqualTo(CharSequence)), _external_ XML entities can be resolved—this is a classic XXE vulnerability.
(from org.assertj.core.util.xml.XmlStringPrettyFormatter)
Vulnerable when *either* is called with untrusted XML strings.
Exploit Example: Reading Arbitrary Files
If an attacker can control the XML input to these methods, they can read sensitive files from your server.
Example Attack XML
<?xml version="1." encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<foo>&xxe;</foo>
Suppose you have a test like
String attackerXml = new String(Files.readAllBytes(Paths.get("attack.xml")), StandardCharsets.UTF_8);
// This will trigger the XXE vulnerability if unpatched:
Assertions.assertThat(attackerXml)
.isXmlEqualTo("<foo>bar</foo>");
Instead of comparing as expected, the XML parser will fetch and insert the contents of /etc/passwd, leaking the file if error messages, logs, or test outputs are seen by the attacker.
Exploitation Scenarios
- Arbitrary file disclosure: Attackers read files such as /etc/passwd, application secrets, environment configurations, AWS credential files, etc.
- Server-Side Request Forgery (SSRF): By referencing http:// or https:// URIs, the attacker can make your server call out to external or internal services.
- Denial of Service: With recursive entities (e.g., Billion Laughs), attackers can crash your service or CI pipeline.
1. Upgrade AssertJ
The fix is available in AssertJ version >= 3.27.7.
Changelog:
- assertj-core release notes 3.27.7
Deprecated since 3.18., removed in 4..
- Recommended: Switch to XMLUnit for XML comparisons.
Migration Example
// Using XMLUnit instead of isXmlEqualTo(CharSequence)
Diff diff = DiffBuilder.compare(expectedXml).withTest(actualXml)
.ignoreWhitespace()
.build();
assertFalse(diff.hasDifferences(), () -> "XMLs differ: " + diff.toString());
If you can't upgrade immediately
- Avoid calling isXmlEqualTo(CharSequence) or XmlStringPrettyFormatter with untrusted or user-controlled strings.
The fixed XmlStringPrettyFormatter.toXmlDocument() disables DTDs and external entities explicitly
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl";, true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities";, false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities";, false);
// other hardening...
References
- AssertJ Security Advisory: XXE in XmlStringPrettyFormatter
- Mitre CVE Listing
- AssertJ Release Notes
- XML External Entity (XXE) Prevention Cheat Sheet (OWASP)
Summary Table
| AssertJ Version | Vulnerable? | Safe? |
|-----------------|-------------|-----------------|
| < 1.4. | Not affected| No XML support |
| 1.4. — 3.27.6 | Yes | |
| 3.27.7+ | | Yes |
| 4..+ | | Yes |
Conclusion
CVE-2026-24400 is a severe XXE vulnerability in AssertJ's XML assertions module. If untrusted input is involved, attackers can read server files, perform SSRF, or crash your system. Upgrade to 3.27.7 or later immediately if you use XML assertions, and switch to safer libraries like XMLUnit for XML comparison.
Stay safe, keep dependencies up-to-date, and never trust user input.
*Exclusively written for you—share and secure your code today!*
Timeline
Published on: 01/26/2026 22:19:02 UTC
Last modified on: 01/27/2026 14:59:34 UTC