diff --git a/api/src/main/java/org/jboss/forge/roaster/model/util/FormatterProfileReader.java b/api/src/main/java/org/jboss/forge/roaster/model/util/FormatterProfileReader.java index 8f77cf4d..e043c422 100644 --- a/api/src/main/java/org/jboss/forge/roaster/model/util/FormatterProfileReader.java +++ b/api/src/main/java/org/jboss/forge/roaster/model/util/FormatterProfileReader.java @@ -15,6 +15,7 @@ import java.util.Properties; import java.util.Set; +import javax.xml.XMLConstants; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -54,6 +55,12 @@ private FormatterProfileReader(InputStream inputStream) throws IOException try { + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + factory.setXIncludeAware(false); SAXParser parser = factory.newSAXParser(); parser.parse(new InputSource(inputStream), handler); } diff --git a/tests/src/test/java/org/jboss/forge/test/roaster/model/util/FormatterProfileReaderTest.java b/tests/src/test/java/org/jboss/forge/test/roaster/model/util/FormatterProfileReaderTest.java index f36cafb6..e250aee0 100644 --- a/tests/src/test/java/org/jboss/forge/test/roaster/model/util/FormatterProfileReaderTest.java +++ b/tests/src/test/java/org/jboss/forge/test/roaster/model/util/FormatterProfileReaderTest.java @@ -7,13 +7,16 @@ package org.jboss.forge.test.roaster.model.util; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import org.jboss.forge.roaster.model.util.FormatterProfileReader; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -43,6 +46,34 @@ public void testFormatterProfileReaderTwoProfiles() throws IOException } } + @Test + public void testXXEAttackIsBlocked() + { + String xxePayload = "\n" + + "\n" + + "]>\n" + + "&xxe;"; + InputStream input = new ByteArrayInputStream(xxePayload.getBytes(StandardCharsets.UTF_8)); + assertThatThrownBy(() -> FormatterProfileReader.fromEclipseXml(input)) + .isInstanceOf(IOException.class); + } + + @Test + public void testBillionLaughsAttackIsBlocked() + { + String billionLaughs = "\n" + + "\n" + + " \n" + + " \n" + + "]>\n" + + "&c;"; + InputStream input = new ByteArrayInputStream(billionLaughs.getBytes(StandardCharsets.UTF_8)); + assertThatThrownBy(() -> FormatterProfileReader.fromEclipseXml(input)) + .isInstanceOf(IOException.class); + } + @Test public void testFormatterProfileReaderOneProfile() throws IOException {