Create secure parser for unmarshalling SP file content
@@ -90,6 +90,7 @@ import org.xml.sax.XMLReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
@@ -115,10 +116,12 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.APPLICATION_ALREADY_EXISTS;
@@ -1981,12 +1984,28 @@ public class ApplicationManagementServiceImpl extends ApplicationManagementServi
" %s uploaded by tenant: %s", spFileContent.getFileName(), tenantDomain));
}
try {
+ //Creating secure parser by disabling XXE
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ spf.setXIncludeAware(false);
+ try {
+ spf.setFeature(Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE, false);
+ spf.setFeature(Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE, false);
+ spf.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE, false);
+ spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (SAXException | ParserConfigurationException e) {
+ log.error("Failed to load XML Processor Feature " + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE + " or "
+ + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE + " or " + Constants.LOAD_EXTERNAL_DTD_FEATURE
+ + " or secure-processing.");
+ }
+ //Creating source object using the secure parser
+ Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(),
+ new InputSource(new StringReader(spFileContent.getContent())));
+ //Performing unmarshall operation by passing the generated source object to the unmarshaller
JAXBContext jaxbContext = JAXBContext.newInstance(ServiceProvider.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- return (ServiceProvider) unmarshaller.unmarshal(new ByteArrayInputStream(
- spFileContent.getContent().getBytes(StandardCharsets.UTF_8)));
-
- } catch (JAXBException e) {
+ return (ServiceProvider) unmarshaller.unmarshal(xmlSource);
+ } catch (JAXBException | SAXException | ParserConfigurationException e) {
throw new IdentityApplicationManagementException(String.format("Error in reading Service Provider " +
"configuration file %s uploaded by tenant: %s", spFileContent.getFileName(), tenantDomain), e);
}
