diff --git a/core/src/main/java/google/registry/xml/XmlTransformer.java b/core/src/main/java/google/registry/xml/XmlTransformer.java index d290ea278..d422d76e8 100644 --- a/core/src/main/java/google/registry/xml/XmlTransformer.java +++ b/core/src/main/java/google/registry/xml/XmlTransformer.java @@ -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; } diff --git a/core/src/test/java/google/registry/flows/EppXmlSanitizerTest.java b/core/src/test/java/google/registry/flows/EppXmlSanitizerTest.java index d7598a609..b27d6118e 100644 --- a/core/src/test/java/google/registry/flows/EppXmlSanitizerTest.java +++ b/core/src/test/java/google/registry/flows/EppXmlSanitizerTest.java @@ -116,4 +116,13 @@ class EppXmlSanitizerTest { String sanitizedXml = sanitizeEppXml(inputXml.getBytes(UTF_16LE)); assertThat(sanitizedXml).isEqualTo(inputXml); } + + @Test + void testSanitize_withDtd_returnsBase64() { + String inputXml = "]>&xxe;"; + 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()); + } }