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
{