1
0
mirror of https://github.com/google/nomulus synced 2026-07-06 00:04:50 +00:00

Harden EppXmlSanitizer against XXE and entity expansion (#3117)

Configure a throwing XMLResolver on XMLInputFactory in XmlTransformer
to act as an additional defense-in-depth security layer against XML
External Entity (XXE) and entity expansion/resolution attacks.
This prevents resolution of external and internal entities in StAX
parsing pipelines, ensuring that malformed payloads containing entity
definitions are safely blocked and rejected.

Also add a unit test to EppXmlSanitizerTest verifying that EPP
messages containing DTD and external entities fail parsing and fall
back safely to their Base64 representation.

TAG=agy
CONV=610c2358-a99f-4605-94cd-ff0d4ee08176

BUG= http://b/529387728
This commit is contained in:
Ben McIlwain
2026-06-30 14:19:50 -04:00
committed by GitHub
parent 67527f1560
commit eda0f7ad7c
2 changed files with 13 additions and 0 deletions
@@ -115,6 +115,10 @@ public class XmlTransformer {
// Prevent XXE attacks.
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xmlInputFactory.setXMLResolver(
(publicID, systemID, baseURI, namespace) -> {
throw new XMLStreamException("Entity resolution disabled.");
});
return xmlInputFactory;
}
@@ -116,4 +116,13 @@ class EppXmlSanitizerTest {
String sanitizedXml = sanitizeEppXml(inputXml.getBytes(UTF_16LE));
assertThat(sanitizedXml).isEqualTo(inputXml);
}
@Test
void testSanitize_withDtd_returnsBase64() {
String inputXml = "<!DOCTYPE foo [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]><pw>&xxe;</pw>";
byte[] inputXmlBytes = inputXml.getBytes(UTF_8);
// Since DTDs are disabled, parsing should fail and fallback to base64 encoding of input.
String expectedBase64 = Base64.getMimeEncoder().encodeToString(inputXmlBytes);
assertThat(sanitizeEppXml(inputXmlBytes).trim()).isEqualTo(expectedBase64.trim());
}
}