diff --git a/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java b/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java
index 3a97db27..5c9a11b6 100644
--- a/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java
+++ b/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java
@@ -20,11 +20,17 @@ import java.lang.reflect.Type;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXSource;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
/**
* Decodes responses using JAXB.
Basic example with with Feign.Builder:
@@ -57,11 +63,25 @@ public class JAXBDecoder implements Decoder { throw new UnsupportedOperationException( "JAXB only supports decoding raw types. Found " + type); } + + try { + SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + /* Explicitly control sax configuration to prevent XXE attacks */ + saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); + saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); + saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + + Source source = new SAXSource(saxParserFactory.newSAXParser().getXMLReader(), new InputSource(response.body().asInputStream())); Unmarshaller unmarshaller = jaxbContextFactory.createUnmarshaller((Class) type); - return unmarshaller.unmarshal(response.body().asInputStream()); + return unmarshaller.unmarshal(source); } catch (JAXBException e) { throw new DecodeException(e.toString(), e); + } catch (ParserConfigurationException e) { + throw new DecodeException(e.toString(), e); + } catch (SAXException e) { + throw new DecodeException(e.toString(), e); } finally { if (response.body() != null) { response.body().close(); diff --git a/sax/src/main/java/feign/sax/SAXDecoder.java b/sax/src/main/java/feign/sax/SAXDecoder.java index 0da7d40f..b0081705 100644 --- a/sax/src/main/java/feign/sax/SAXDecoder.java +++ b/sax/src/main/java/feign/sax/SAXDecoder.java @@ -74,6 +74,11 @@ public class SAXDecoder implements Decoder { XMLReader xmlReader = XMLReaderFactory.createXMLReader(); xmlReader.setFeature("http://xml.org/sax/features/namespaces", false); xmlReader.setFeature("http://xml.org/sax/features/validation", false); + /* Explicitly control sax configuration to prevent XXE attacks */ + xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); + xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false); + xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); xmlReader.setContentHandler(handler); InputStream inputStream = response.body().asInputStream(); try {