Fix CVE-2026-24400: XXE vulnerability in assertj-core
Add a patch to fix CVE-2026-24400 by enabling secure XML
parsing features in XmlStringPrettyFormatter. The patch
disables DOCTYPE declarations and external entity processing
to prevent XXE (XML External Entity) attacks. Backported from
upstream commit 77081dc5eb107141df80f95bd0149b468e451341,
adapted for the 3.24.2 source tree. Includes two new test
cases verifying that XML strings containing DOCTYPE with
general and parameter entities are properly rejected.
CVE: CVE-2026-24400
Upstream patches:
- 77081dc5eb.patch
Resolves: RHEL-208838
This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.
Assisted-by: Ymir
This commit is contained in:
parent
def7008f83
commit
55e257df96
120
assertj-core-3.24.2-CVE-2026-24400.patch
Normal file
120
assertj-core-3.24.2-CVE-2026-24400.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From a89c9ad8443985ee4dd05452b7a589328fa3b157 Mon Sep 17 00:00:00 2001
|
||||
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
|
||||
Date: Thu, 25 Jun 2026 12:40:54 +0000
|
||||
Subject: [PATCH] Add XXE protection to XmlStringPrettyFormatter
|
||||
|
||||
Add secure XML parsing features to prevent XXE attacks by disabling
|
||||
DOCTYPE declarations and external entity processing.
|
||||
|
||||
Adapted for 3.24.2: keep tests in the old location.
|
||||
---
|
||||
.../util/xml/XmlStringPrettyFormatter.java | 27 ++++++++++++++-
|
||||
...ringPrettyFormatter_prettyFormat_Test.java | 33 +++++++++++++++++++
|
||||
2 files changed, 59 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/assertj-core/src/main/java/org/assertj/core/util/xml/XmlStringPrettyFormatter.java b/assertj-core/src/main/java/org/assertj/core/util/xml/XmlStringPrettyFormatter.java
|
||||
index 33c035b33..b66b9858b 100644
|
||||
--- a/assertj-core/src/main/java/org/assertj/core/util/xml/XmlStringPrettyFormatter.java
|
||||
+++ b/assertj-core/src/main/java/org/assertj/core/util/xml/XmlStringPrettyFormatter.java
|
||||
@@ -17,9 +17,13 @@ import static org.assertj.core.util.Preconditions.checkArgument;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
|
||||
+import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
+import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
|
||||
@@ -39,6 +43,17 @@ public class XmlStringPrettyFormatter {
|
||||
|
||||
private static final String FORMAT_ERROR = "Unable to format XML string";
|
||||
|
||||
+ // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
+ private static final Map<String, Boolean> SECURE_FEATURES = new HashMap<>();
|
||||
+
|
||||
+ static {
|
||||
+ SECURE_FEATURES.put(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
+ SECURE_FEATURES.put("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
+ SECURE_FEATURES.put("http://xml.org/sax/features/external-general-entities", false);
|
||||
+ SECURE_FEATURES.put("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
+ SECURE_FEATURES.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
+ }
|
||||
+
|
||||
public static String xmlPrettyFormat(String xmlStringToFormat) {
|
||||
checkArgument(xmlStringToFormat != null, "Expecting XML String not to be null");
|
||||
// convert String to an XML Document and then back to String but prettily formatted.
|
||||
@@ -67,13 +82,23 @@ public class XmlStringPrettyFormatter {
|
||||
private static Document toXmlDocument(String xmlString) {
|
||||
try {
|
||||
InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
|
||||
- DocumentBuilder xmlDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
+ DocumentBuilder xmlDocumentBuilder = documentBuilderFactory().newDocumentBuilder();
|
||||
return xmlDocumentBuilder.parse(xmlInputSource);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(FORMAT_ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
+ private static DocumentBuilderFactory documentBuilderFactory() {
|
||||
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
+ SECURE_FEATURES.forEach((name, value) -> {
|
||||
+ try {
|
||||
+ factory.setFeature(name, value);
|
||||
+ } catch (ParserConfigurationException ignore) {}
|
||||
+ });
|
||||
+ return factory;
|
||||
+ }
|
||||
+
|
||||
private XmlStringPrettyFormatter() {
|
||||
// utility class
|
||||
}
|
||||
diff --git a/assertj-core/src/test/java/org/assertj/core/util/xml/XmlStringPrettyFormatter_prettyFormat_Test.java b/assertj-core/src/test/java/org/assertj/core/util/xml/XmlStringPrettyFormatter_prettyFormat_Test.java
|
||||
index 2c1bf754e..1600e1306 100644
|
||||
--- a/assertj-core/src/test/java/org/assertj/core/util/xml/XmlStringPrettyFormatter_prettyFormat_Test.java
|
||||
+++ b/assertj-core/src/test/java/org/assertj/core/util/xml/XmlStringPrettyFormatter_prettyFormat_Test.java
|
||||
@@ -97,4 +97,37 @@ class XmlStringPrettyFormatter_prettyFormat_Test {
|
||||
}
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ void should_throw_error_when_xml_string_contains_doctype_with_entity() {
|
||||
+ String xmlString = "<?xml version=\"1.0\"?>\n"
|
||||
+ + "<!DOCTYPE root [\n"
|
||||
+ + " <!ENTITY xxe SYSTEM \"file:///etc/hosts\">\n"
|
||||
+ + "]>\n"
|
||||
+ + "<root>&xxe;</root>";
|
||||
+ try {
|
||||
+ xmlPrettyFormat(xmlString);
|
||||
+ } catch (Exception e) {
|
||||
+ assertThat(e).isInstanceOf(RuntimeException.class).hasMessageStartingWith("Unable to format XML string");
|
||||
+ assertThat(e).hasRootCauseInstanceOf(SAXParseException.class);
|
||||
+ assertThat(e.getCause()).hasMessageContaining("DOCTYPE is disallowed");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ void should_throw_error_when_xml_string_contains_doctype_with_parameter_entity() {
|
||||
+ String xmlString = "<?xml version=\"1.0\"?>\n"
|
||||
+ + "<!DOCTYPE root [\n"
|
||||
+ + " <!ENTITY % xxe SYSTEM \"file:///etc/hosts\">\n"
|
||||
+ + " %xxe;\n"
|
||||
+ + "]>\n"
|
||||
+ + "<root>foo</root>";
|
||||
+ try {
|
||||
+ xmlPrettyFormat(xmlString);
|
||||
+ } catch (Exception e) {
|
||||
+ assertThat(e).isInstanceOf(RuntimeException.class).hasMessageStartingWith("Unable to format XML string");
|
||||
+ assertThat(e).hasRootCauseInstanceOf(SAXParseException.class);
|
||||
+ assertThat(e.getCause()).hasMessageContaining("DOCTYPE is disallowed");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
|
||||
Name: assertj-core
|
||||
Version: 3.24.2
|
||||
Release: 9%{?dist}
|
||||
Release: 10%{?dist}
|
||||
Summary: Library of assertions similar to fest-assert
|
||||
License: Apache-2.0
|
||||
URL: https://joel-costigliola.github.io/assertj/
|
||||
Source0: https://github.com/joel-costigliola/assertj-core/archive/assertj-build-%{version}.tar.gz
|
||||
|
||||
# https://github.com/assertj/assertj/commit/77081dc5eb107141df80f95bd0149b468e451341
|
||||
Patch0: assertj-core-3.24.2-CVE-2026-24400.patch
|
||||
|
||||
BuildArch: noarch
|
||||
ExclusiveArch: %{java_arches} noarch
|
||||
|
||||
@ -34,6 +37,7 @@ This package provides API documentation for %{name}.
|
||||
|
||||
%prep
|
||||
%setup -q -n assertj-assertj-build-%{version}
|
||||
%patch -P0 -p1
|
||||
|
||||
%pom_remove_plugin -r :maven-javadoc-plugin
|
||||
%pom_remove_plugin -r :maven-enforcer-plugin
|
||||
@ -80,6 +84,10 @@ This package provides API documentation for %{name}.
|
||||
%license LICENSE.txt
|
||||
|
||||
%changelog
|
||||
* Thu Jun 25 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 3.24.2-10
|
||||
- Fix CVE-2026-24400: add XXE protection to XmlStringPrettyFormatter
|
||||
- Resolves: RHEL-208838
|
||||
|
||||
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 3.24.2-9
|
||||
- Bump release for October 2024 mass rebuild:
|
||||
Resolves: RHEL-64018
|
||||
|
||||
Loading…
Reference in New Issue
Block a user