You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/03/09 14:46:18 UTC

[3/4] syncope git commit: Ensuring secure XSLT processing everywhere

Ensuring secure XSLT processing everywhere


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/717289bc
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/717289bc
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/717289bc

Branch: refs/heads/master
Commit: 717289bc10b6f3b204cb6d14881f530174c62359
Parents: 1edec31
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Mar 7 11:55:21 2018 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Mar 9 15:22:40 2018 +0100

----------------------------------------------------------------------
 .../configuration/ConfigurationExport.java      | 24 +------
 .../commands/report/ReportExportExecution.java  | 31 +++------
 .../report/ReportSyncopeOperations.java         |  6 +-
 .../syncope/client/cli/util/XMLUtils.java       | 33 ++++-----
 .../core/logic/cocoon/XSLTTransformer.java      | 13 +++-
 .../jpa/content/XMLContentExporter.java         |  5 +-
 .../job/report/DefaultReportJobDelegate.java    | 19 +++++-
 .../core/logic/init/CamelRouteLoader.java       | 13 ++--
 .../core/logic/saml2/SAML2ReaderWriter.java     |  5 +-
 .../apache/syncope/fit/core/ReportITCase.java   | 71 +++++++++++---------
 .../syncope/fit/core/ReportTemplateITCase.java  | 36 ++++++++++
 .../installer/processes/ArchetypeProcess.java   | 35 +++-------
 .../installer/processes/ContainerProcess.java   | 32 ++-------
 .../installer/utilities/FileSystemUtils.java    |  3 +-
 .../syncope/installer/utilities/MavenUtils.java | 29 ++++----
 15 files changed, 169 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/client/cli/src/main/java/org/apache/syncope/client/cli/commands/configuration/ConfigurationExport.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/configuration/ConfigurationExport.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/configuration/ConfigurationExport.java
index f0b8c31..d86a95d 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/configuration/ConfigurationExport.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/configuration/ConfigurationExport.java
@@ -18,18 +18,12 @@
  */
 package org.apache.syncope.client.cli.commands.configuration;
 
-import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.InputStream;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
 import org.apache.syncope.client.cli.Input;
 import org.apache.syncope.client.cli.util.XMLUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
 
 public class ConfigurationExport extends AbstractConfigurationCommand {
 
@@ -53,24 +47,12 @@ public class ConfigurationExport extends AbstractConfigurationCommand {
                         input.firstParameter() + EXPORT_FILE_NAME);
                 configurationResultManager.genericMessage(
                         input.firstParameter() + EXPORT_FILE_NAME + " successfully created");
-            } catch (final IOException ex) {
-                LOG.error("Error exporting configuration", ex);
-                configurationResultManager.genericError(ex.getMessage());
-            } catch (ParserConfigurationException | SAXException | TransformerConfigurationException ex) {
-                LOG.error("Error exporting configuration", ex);
-                configurationResultManager.genericError(
-                        "Error creating " + input.firstParameter() + EXPORT_FILE_NAME + " " + ex.getMessage());
-            } catch (final TransformerException ex) {
-                LOG.error("Error exporting configuration", ex);
-                if (ex.getCause() instanceof FileNotFoundException) {
-                    configurationResultManager.genericError("Permission denied on " + input.firstParameter());
-                } else {
-                    configurationResultManager.genericError(
-                            "Error creating " + input.firstParameter() + EXPORT_FILE_NAME + " " + ex.getMessage());
-                }
             } catch (final SyncopeClientException ex) {
                 LOG.error("Error exporting configuration", ex);
                 configurationResultManager.genericError("Error calling configuration service " + ex.getMessage());
+            } catch (final Exception ex) {
+                LOG.error("Error exporting configuration", ex);
+                configurationResultManager.genericError(ex.getMessage());
             }
         } else {
             configurationResultManager.commandOptionError(EXPORT_HELP_MESSAGE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportExportExecution.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportExportExecution.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportExportExecution.java
index f520254..cbbaff1 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportExportExecution.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportExportExecution.java
@@ -18,25 +18,19 @@
  */
 package org.apache.syncope.client.cli.commands.report;
 
-import java.io.IOException;
 import java.util.Arrays;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
 import javax.xml.ws.WebServiceException;
 import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.client.cli.util.CommandUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
 
 public class ReportExportExecution extends AbstractReportCommand {
 
     private static final Logger LOG = LoggerFactory.getLogger(ReportExportExecution.class);
 
-    private static final String EXPORT_EXECUTION_HELP_MESSAGE
-            = "report --export-execution-result {EXECUTION-KEY} {EXECUTION-KEY} [...] {FORMAT}\n"
+    private static final String EXPORT_EXECUTION_HELP_MESSAGE =
+            "report --export-execution-result {EXECUTION-KEY} {EXECUTION-KEY} [...] {FORMAT}\n"
             + "          Format: CSV / HTML / PDF / XML / RTF";
 
     private final Input input;
@@ -50,28 +44,19 @@ public class ReportExportExecution extends AbstractReportCommand {
             final String[] parameters = Arrays.copyOf(input.getParameters(), input.parameterNumber() - 1);
             for (final String parameter : parameters) {
                 try {
-                    final String result = reportSyncopeOperations.exportExecutionResult(
-                            parameter, input.lastParameter());
+                    String result = reportSyncopeOperations.exportExecutionResult(parameter, input.lastParameter());
                     reportResultManager.genericMessage(result + "created.");
-                } catch (final WebServiceException | SyncopeClientException ex) {
-                    LOG.error("Error exporting execution", ex);
-                    if (ex.getMessage().startsWith("NotFound")) {
+                } catch (final WebServiceException | SyncopeClientException e) {
+                    LOG.error("Error exporting execution", e);
+                    if (e.getMessage().startsWith("NotFound")) {
                         reportResultManager.notFoundError("Report", parameter);
                     } else {
-                        reportResultManager.genericError(ex.getMessage());
+                        reportResultManager.genericError(e.getMessage());
                     }
-                } catch (final NumberFormatException ex) {
-                    LOG.error("Error exporting execution", ex);
-                    reportResultManager.numberFormatException("report", parameter);
-                } catch (IOException | ParserConfigurationException | SAXException | TransformerException e) {
+                } catch (final Exception e) {
                     LOG.error("Error exporting execution", e);
                     reportResultManager.genericError(
                             " - Error creating " + "export_" + parameter + " " + e.getMessage());
-                } catch (final IllegalArgumentException ex) {
-                    LOG.error("Error exporting execution", ex);
-                    reportResultManager.typeNotValidError(
-                            "format", input.firstParameter(),
-                            CommandUtils.fromEnumToArray(ReportExecExportFormat.class));
                 }
                 break;
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
index 0109d5e..17c6efa 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/report/ReportSyncopeOperations.java
@@ -18,14 +18,11 @@
  */
 package org.apache.syncope.client.cli.commands.report;
 
-import java.io.IOException;
 import java.io.OutputStream;
 import java.io.SequenceInputStream;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.List;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.client.cli.SyncopeServices;
 import org.apache.syncope.client.cli.util.XMLUtils;
@@ -34,7 +31,6 @@ import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
 import org.apache.syncope.common.rest.api.service.ReportService;
-import org.xml.sax.SAXException;
 
 public class ReportSyncopeOperations {
 
@@ -53,7 +49,7 @@ public class ReportSyncopeOperations {
     }
 
     public String exportExecutionResult(final String executionKey, final String reportExecExportFormat)
-            throws TransformerException, SAXException, IOException, ParserConfigurationException {
+            throws Exception {
 
         ReportExecExportFormat format = ReportExecExportFormat.valueOf(reportExecExportFormat);
         SequenceInputStream report = (SequenceInputStream) reportService.exportExecutionResult(executionKey, format).

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/client/cli/src/main/java/org/apache/syncope/client/cli/util/XMLUtils.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/util/XMLUtils.java b/client/cli/src/main/java/org/apache/syncope/client/cli/util/XMLUtils.java
index ad3cf39..93754d6 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/util/XMLUtils.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/util/XMLUtils.java
@@ -19,34 +19,29 @@
 package org.apache.syncope.client.cli.util;
 
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringReader;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
+import javax.xml.XMLConstants;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-import org.apache.cxf.helpers.IOUtils;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSParser;
 
 public final class XMLUtils {
 
-    public static void createXMLFile(final InputStream sis, final String filePath)
-            throws TransformerException, SAXException, IOException, ParserConfigurationException {
-
-        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-        dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+    public static void createXMLFile(final InputStream sis, final String filePath) throws Exception {
+        DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
+        DOMImplementationLS domImpl = (DOMImplementationLS) reg.getDOMImplementation("LS");
+        LSInput lsinput = domImpl.createLSInput();
+        lsinput.setByteStream(sis);
+        LSParser parser = domImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
 
         TransformerFactory tf = TransformerFactory.newInstance();
-        tf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
-        
-        tf.newTransformer().
-                transform(new DOMSource(dbf.newDocumentBuilder().
-                        parse(new InputSource(new StringReader(IOUtils.toString(sis))))),
-                        new StreamResult(new File(filePath)));
+        tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+
+        tf.newTransformer().transform(new DOMSource(parser.parse(lsinput)), new StreamResult(new File(filePath)));
     }
 
     private XMLUtils() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/core/logic/src/main/java/org/apache/syncope/core/logic/cocoon/XSLTTransformer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/cocoon/XSLTTransformer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/cocoon/XSLTTransformer.java
index 92b797f..6e969be 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/cocoon/XSLTTransformer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/cocoon/XSLTTransformer.java
@@ -19,11 +19,11 @@ package org.apache.syncope.core.logic.cocoon;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
+import javax.xml.XMLConstants;
 import javax.xml.transform.Source;
 import javax.xml.transform.Templates;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
@@ -151,7 +151,7 @@ public class XSLTTransformer extends AbstractSAXTransformer implements CachingPi
         if (this.parameters != null) {
             final Transformer transformer = transformerHandler.getTransformer();
 
-            this.parameters.forEach((name, values)-> {
+            this.parameters.forEach((name, values) -> {
                 // is valid XSLT parameter name
                 if (XSLT_PARAMETER_NAME_PATTERN.matcher(name).matches()) {
                     transformer.setParameter(name, values);
@@ -181,7 +181,14 @@ public class XSLTTransformer extends AbstractSAXTransformer implements CachingPi
      * @return a new transformer factory
      */
     private static SAXTransformerFactory createNewSAXTransformerFactory() {
-        return (SAXTransformerFactory) TransformerFactory.newInstance();
+        SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+        transformerFactory.setURIResolver((href, base) -> null);
+        try {
+            transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        } catch (TransformerConfigurationException e) {
+            LOG.error("Could not enable secure XML processing", e);
+        }
+        return transformerFactory;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index 6ff27ab..4909ed3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -43,6 +43,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 import javax.sql.DataSource;
 import javax.xml.bind.DatatypeConverter;
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
@@ -360,8 +361,8 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
         }
 
         StreamResult streamResult = new StreamResult(os);
-        final SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-        transformerFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+        transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 
         TransformerHandler handler = transformerFactory.newTransformerHandler();
         Transformer serializer = handler.getTransformer();

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
index 1d8cd4f..e4050b7 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/DefaultReportJobDelegate.java
@@ -27,8 +27,11 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.zip.Deflater;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
@@ -55,6 +58,18 @@ public class DefaultReportJobDelegate implements ReportJobDelegate {
 
     private static final Logger LOG = LoggerFactory.getLogger(ReportJobDelegate.class);
 
+    private static final SAXTransformerFactory TRANSFORMER_FACTORY;
+
+    static {
+        TRANSFORMER_FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
+        TRANSFORMER_FACTORY.setURIResolver((href, base) -> null);
+        try {
+            TRANSFORMER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        } catch (TransformerConfigurationException e) {
+            LOG.error("Could not enable secure XML processing", e);
+        }
+    }
+
     /**
      * Report DAO.
      */
@@ -121,9 +136,7 @@ public class DefaultReportJobDelegate implements ReportJobDelegate {
         ZipOutputStream zos = new ZipOutputStream(baos);
         zos.setLevel(Deflater.BEST_COMPRESSION);
         try {
-            SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-            tFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
-            handler = tFactory.newTransformerHandler();
+            handler = TRANSFORMER_FACTORY.newTransformerHandler();
             Transformer serializer = handler.getTransformer();
             serializer.setOutputProperty(OutputKeys.ENCODING, StandardCharsets.UTF_8.name());
             serializer.setOutputProperty(OutputKeys.INDENT, "yes");

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index 4a3e577..44f9c8a 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -21,8 +21,7 @@ package org.apache.syncope.core.logic.init;
 import java.io.StringWriter;
 import java.util.Map;
 import javax.sql.DataSource;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
@@ -30,6 +29,7 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CamelEntitlement;
 import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
@@ -153,11 +153,10 @@ public class CamelRouteLoader implements SyncopeLoader {
                 NodeList routeNodes;
                 if (IS_JBOSS) {
                     tf = TransformerFactory.newInstance();
-                    tf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
-                    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-                    dbFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
-                    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-                    Document doc = dBuilder.parse(resource.getInputStream());
+                    tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+                    tf.setURIResolver((href, base) -> null);
+
+                    Document doc = StaxUtils.read(resource.getInputStream());
 
                     routeNodes = doc.getDocumentElement().getElementsByTagName("route");
                 } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index 090009c..09ae7be 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -77,6 +77,7 @@ public class SAML2ReaderWriter {
 
     static {
         TRANSFORMER_FACTORY = TransformerFactory.newInstance();
+        TRANSFORMER_FACTORY.setURIResolver((href, base) -> null);
         try {
             TRANSFORMER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
         } catch (TransformerConfigurationException e) {
@@ -103,14 +104,14 @@ public class SAML2ReaderWriter {
         // Try to load a signature algorithm
         if (loader.getSignatureAlgorithm() != null) {
             SignatureAlgorithm loadedSignatureAlgorithm =
-                SignatureAlgorithm.valueOf(loader.getSignatureAlgorithm());
+                    SignatureAlgorithm.valueOf(loader.getSignatureAlgorithm());
             if (loadedSignatureAlgorithm != null) {
                 sigAlgo = loadedSignatureAlgorithm.getAlgorithm();
                 jceSigAlgo = JCEMapper.translateURItoJCEID(sigAlgo);
             }
             if (jceSigAlgo == null) {
                 LOG.warn("Signature algorithm {} is not valid. Using default algorithm instead.",
-                         loader.getSignatureAlgorithm());
+                        loader.getSignatureAlgorithm());
                 sigAlgo = null;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
index 0100d5a..09f7b02 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java
@@ -59,6 +59,40 @@ import org.junit.jupiter.api.Test;
 
 public class ReportITCase extends AbstractITCase {
 
+    protected static String execReport(final String reportKey) {
+        ReportTO reportTO = reportService.read(reportKey);
+        assertNotNull(reportTO);
+        assertNotNull(reportTO.getExecutions());
+
+        int preExecSize = reportTO.getExecutions().size();
+        ExecTO exec = reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
+        assertNotNull(exec);
+
+        int i = 0;
+        int maxit = 50;
+
+        // wait for completion (executions incremented)
+        do {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            reportTO = reportService.read(reportKey);
+
+            assertNotNull(reportTO);
+            assertNotNull(reportTO.getExecutions());
+
+            i++;
+        } while (preExecSize == reportTO.getExecutions().size() && i < maxit);
+        if (i == maxit) {
+            fail("Timeout when executing report " + reportKey);
+        }
+        exec = reportTO.getExecutions().get(reportTO.getExecutions().size() - 1);
+        assertEquals(ReportExecStatus.SUCCESS.name(), exec.getStatus());
+        return exec.getKey();
+    }
+
     @Test
     public void getReportletConfs() {
         Set<String> reportletConfs = syncopeService.platform().
@@ -201,35 +235,6 @@ public class ReportITCase extends AbstractITCase {
         }
     }
 
-    private String execute(final String reportKey) {
-        ExecTO execution = reportService.execute(new ExecuteQuery.Builder().key(reportKey).build());
-        assertNotNull(execution);
-
-        int i = 0;
-        int maxit = 50;
-
-        ReportTO reportTO;
-
-        // wait for report execution completion (executions incremented)
-        do {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-            }
-
-            reportTO = reportService.read(reportKey);
-
-            assertNotNull(reportTO);
-            assertNotNull(reportTO.getExecutions());
-
-            i++;
-        } while (reportTO.getExecutions().isEmpty()
-                || (!ReportExecStatus.SUCCESS.name().equals(reportTO.getExecutions().get(0).getStatus()) && i < maxit));
-        assertEquals(ReportExecStatus.SUCCESS.name(), reportTO.getExecutions().get(0).getStatus());
-
-        return reportTO.getExecutions().get(0).getKey();
-    }
-
     private void checkExport(final String execKey, final ReportExecExportFormat fmt) throws IOException {
         Response response = reportService.exportExecutionResult(execKey, fmt);
         assertNotNull(response);
@@ -254,7 +259,7 @@ public class ReportITCase extends AbstractITCase {
         assertNotNull(reportTO);
 
         try {
-            execute(reportTO.getKey());
+            execReport(reportTO.getKey());
             fail("This should not happen");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.Scheduling, e.getType());
@@ -264,7 +269,7 @@ public class ReportITCase extends AbstractITCase {
         reportTO.setActive(true);
         reportService.update(reportTO);
 
-        String execKey = execute(reportTO.getKey());
+        String execKey = execReport(reportTO.getKey());
 
         checkExport(execKey, ReportExecExportFormat.XML);
         checkExport(execKey, ReportExecExportFormat.HTML);
@@ -288,7 +293,7 @@ public class ReportITCase extends AbstractITCase {
         reportTO = createReport(reportTO);
         assertNotNull(reportTO);
 
-        String execKey = execute(reportTO.getKey());
+        String execKey = execReport(reportTO.getKey());
         assertNotNull(execKey);
 
         try {
@@ -336,7 +341,7 @@ public class ReportITCase extends AbstractITCase {
             report.setTemplate("sample");
             report = createReport(report);
 
-            String execKey = execute(report.getKey());
+            String execKey = execReport(report.getKey());
             checkExport(execKey, ReportExecExportFormat.XML);
 
             report = reportService.read(report.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
index 6e7fc60..68bbb51 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
@@ -34,6 +34,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ReportTemplateTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.lib.types.ReportTemplateFormat;
 import org.apache.syncope.fit.AbstractITCase;
 import org.junit.jupiter.api.Test;
@@ -151,6 +152,41 @@ public class ReportTemplateITCase extends AbstractITCase {
     }
 
     @Test
+    public void safeTemplate() throws IOException {
+        Response response = reportTemplateService.getFormat("sample", ReportTemplateFormat.HTML);
+        String before = IOUtils.toString((InputStream) response.getEntity(), StandardCharsets.UTF_8);
+        assertNotNull(before);
+
+        String execKey = ReportITCase.execReport("0062ea9c-924d-4ecf-9961-4492a8cc6d1b");
+        assertNotNull(execKey);
+        response = reportService.exportExecutionResult(execKey, ReportExecExportFormat.HTML);
+        String result = IOUtils.toString((InputStream) response.getEntity(), StandardCharsets.UTF_8);
+        assertNotNull(result);
+        assertTrue(result.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
+                + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"));
+
+        String malicious = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+                + "<!DOCTYPE xsl:stylesheet "
+                + "[<!ENTITY file SYSTEM \"webapps/syncope/WEB-INF/classes/security.properties\">]>\n"
+                + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
+                + "    <xsl:template match=\"/\">&file;</xsl:template>\n"
+                + "</xsl:stylesheet>";
+        try {
+            reportTemplateService.setFormat("sample", ReportTemplateFormat.HTML,
+                    IOUtils.toInputStream(malicious, StandardCharsets.UTF_8));
+
+            response = reportService.exportExecutionResult(execKey, ReportExecExportFormat.HTML);
+            result = IOUtils.toString((InputStream) response.getEntity(), StandardCharsets.UTF_8);
+            assertNotNull(result);
+            assertTrue(result.isEmpty());
+        } finally {
+            reportTemplateService.setFormat("sample", ReportTemplateFormat.HTML,
+                    IOUtils.toInputStream(before, StandardCharsets.UTF_8));
+        }
+    }
+
+    @Test
     public void issueSYNCOPE866() {
         ReportTemplateTO reportTemplateTO = new ReportTemplateTO();
         reportTemplateTO.setKey("empty");

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/installer/src/main/java/org/apache/syncope/installer/processes/ArchetypeProcess.java
----------------------------------------------------------------------
diff --git a/installer/src/main/java/org/apache/syncope/installer/processes/ArchetypeProcess.java b/installer/src/main/java/org/apache/syncope/installer/processes/ArchetypeProcess.java
index b18d2de..a530867 100644
--- a/installer/src/main/java/org/apache/syncope/installer/processes/ArchetypeProcess.java
+++ b/installer/src/main/java/org/apache/syncope/installer/processes/ArchetypeProcess.java
@@ -21,16 +21,12 @@ package org.apache.syncope.installer.processes;
 import org.apache.syncope.installer.utilities.FileSystemUtils;
 import com.izforge.izpack.panels.process.AbstractUIProcessHandler;
 import java.io.File;
-import java.io.IOException;
 import java.util.Properties;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
 import org.apache.syncope.installer.files.ConsolePom;
 import org.apache.syncope.installer.files.CorePom;
 import org.apache.syncope.installer.files.ParentPom;
 import org.apache.syncope.installer.utilities.InstallLog;
 import org.apache.syncope.installer.utilities.MavenUtils;
-import org.xml.sax.SAXException;
 
 public class ArchetypeProcess extends BaseProcess {
 
@@ -65,30 +61,15 @@ public class ArchetypeProcess extends BaseProcess {
         InstallLog.initialize(installPath, handler);
         MavenUtils mavenUtils = new MavenUtils(mavenDir, handler);
         File customMavenProxySettings = null;
-        try {
-            if (isProxyEnabled && mavenProxyAutoconf) {
-                customMavenProxySettings = MavenUtils.createSettingsWithProxy(installPath, proxyHost, proxyPort,
-                        proxyUser, proxyPwd);
+        if (isProxyEnabled && mavenProxyAutoconf) {
+            try {
+                customMavenProxySettings =
+                        MavenUtils.createSettingsWithProxy(installPath, proxyHost, proxyPort, proxyUser, proxyPwd);
+            } catch (Exception e) {
+                StringBuilder message = new StringBuilder("Error during creation of custom Maven settings.xml");
+                handler.emitError(message.toString(), e.getMessage());
+                InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
             }
-        } catch (IOException e) {
-            StringBuilder message = new StringBuilder("I/O error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (ParserConfigurationException e) {
-            StringBuilder message = new StringBuilder(
-                    "Parser configuration error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (TransformerException e) {
-            StringBuilder message = new StringBuilder(
-                    "Transformer error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (SAXException e) {
-            StringBuilder message = new StringBuilder(
-                    "XML parsing error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
         }
 
         handler.logOutput("########################## IMPORTANT ##########################", true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/installer/src/main/java/org/apache/syncope/installer/processes/ContainerProcess.java
----------------------------------------------------------------------
diff --git a/installer/src/main/java/org/apache/syncope/installer/processes/ContainerProcess.java b/installer/src/main/java/org/apache/syncope/installer/processes/ContainerProcess.java
index 954c8e7..0429c30 100644
--- a/installer/src/main/java/org/apache/syncope/installer/processes/ContainerProcess.java
+++ b/installer/src/main/java/org/apache/syncope/installer/processes/ContainerProcess.java
@@ -21,10 +21,7 @@ package org.apache.syncope.installer.processes;
 import org.apache.syncope.installer.utilities.FileSystemUtils;
 import com.izforge.izpack.panels.process.AbstractUIProcessHandler;
 import java.io.File;
-import java.io.IOException;
 import java.util.Properties;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
 import org.apache.syncope.installer.containers.Glassfish;
 import org.apache.syncope.installer.containers.Tomcat;
 import org.apache.syncope.installer.containers.jboss.JBoss;
@@ -35,7 +32,6 @@ import org.apache.syncope.installer.files.GlassfishCoreWebXml;
 import org.apache.syncope.installer.files.MasterDomainXml;
 import org.apache.syncope.installer.utilities.InstallLog;
 import org.apache.syncope.installer.utilities.MavenUtils;
-import org.xml.sax.SAXException;
 
 public final class ContainerProcess extends BaseProcess {
 
@@ -76,6 +72,7 @@ public final class ContainerProcess extends BaseProcess {
     private String logsDirectory;
 
     private String bundlesDirectory;
+
     private String modelerDirectory;
 
     private boolean withDataSource;
@@ -199,30 +196,15 @@ public final class ContainerProcess extends BaseProcess {
 
         MavenUtils mavenUtils = new MavenUtils(mavenDir, handler);
         File customMavenProxySettings = null;
-        try {
-            if (isProxyEnabled && mavenProxyAutoconf) {
+        if (isProxyEnabled && mavenProxyAutoconf) {
+            try {
                 customMavenProxySettings = MavenUtils.createSettingsWithProxy(
                         installPath, proxyHost, proxyPort, proxyUser, proxyPwd);
+            } catch (Exception e) {
+                StringBuilder message = new StringBuilder("Error during creation of custom Maven settings.xml");
+                handler.emitError(message.toString(), e.getMessage());
+                InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
             }
-        } catch (IOException e) {
-            StringBuilder message = new StringBuilder("I/O error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (ParserConfigurationException e) {
-            StringBuilder message = new StringBuilder(
-                    "Parser configuration error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (TransformerException e) {
-            StringBuilder message = new StringBuilder(
-                    "Transformer error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
-        } catch (SAXException e) {
-            StringBuilder message = new StringBuilder(
-                    "XML parsing error during creation of Maven custom settings.xml");
-            handler.emitError(message.toString(), e.getMessage());
-            InstallLog.getInstance().error(message.append('\n').append(e.getMessage()).toString());
         }
 
         Properties mvnProperties = new Properties();

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/installer/src/main/java/org/apache/syncope/installer/utilities/FileSystemUtils.java
----------------------------------------------------------------------
diff --git a/installer/src/main/java/org/apache/syncope/installer/utilities/FileSystemUtils.java b/installer/src/main/java/org/apache/syncope/installer/utilities/FileSystemUtils.java
index f84538b..e89cdac 100644
--- a/installer/src/main/java/org/apache/syncope/installer/utilities/FileSystemUtils.java
+++ b/installer/src/main/java/org/apache/syncope/installer/utilities/FileSystemUtils.java
@@ -30,6 +30,7 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.nio.charset.Charset;
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
@@ -135,7 +136,7 @@ public class FileSystemUtils {
 
     public static void writeXML(final Document doc, final OutputStream out) throws IOException, TransformerException {
         final TransformerFactory factory = TransformerFactory.newInstance();
-        factory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
         final Transformer transformer = factory.newTransformer();
         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
         transformer.setOutputProperty(OutputKeys.METHOD, "xml");

http://git-wip-us.apache.org/repos/asf/syncope/blob/717289bc/installer/src/main/java/org/apache/syncope/installer/utilities/MavenUtils.java
----------------------------------------------------------------------
diff --git a/installer/src/main/java/org/apache/syncope/installer/utilities/MavenUtils.java b/installer/src/main/java/org/apache/syncope/installer/utilities/MavenUtils.java
index 27f0c2a..b704247 100644
--- a/installer/src/main/java/org/apache/syncope/installer/utilities/MavenUtils.java
+++ b/installer/src/main/java/org/apache/syncope/installer/utilities/MavenUtils.java
@@ -20,20 +20,14 @@ package org.apache.syncope.installer.utilities;
 
 import com.izforge.izpack.panels.process.AbstractUIProcessHandler;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
 import org.apache.maven.shared.invoker.DefaultInvoker;
@@ -47,7 +41,10 @@ import org.jasypt.commons.CommonUtils;
 import org.jasypt.digest.StandardStringDigester;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSParser;
 
 public class MavenUtils {
 
@@ -81,7 +78,7 @@ public class MavenUtils {
         request.setBatchMode(true);
         final Properties properties =
                 archetypeProperties(archetypeVersion, groupId, artifactId, secretKey,
-                                    anonymousKey, jwsKey, adminPassword);
+                        anonymousKey, jwsKey, adminPassword);
         request.setProperties(properties);
         if (customSettingsFile != null && FileUtils.sizeOf(customSettingsFile) > 0) {
             request.setUserSettingsFile(customSettingsFile);
@@ -183,19 +180,21 @@ public class MavenUtils {
     }
 
     public static File createSettingsWithProxy(final String path, final String proxyHost, final String proxyPort,
-            final String proxyUser, final String proxyPassword) throws IOException, ParserConfigurationException,
-            TransformerException, SAXException {
+            final String proxyUser, final String proxyPassword) throws Exception {
+
         final File settingsXML = new File(System.getProperty(MAVEN_HOME_PROPERTY) + (System.getProperty(
                 MAVEN_HOME_PROPERTY).endsWith("/") ? "conf/settings.xml" : "/conf/settings.xml"));
         final File tempSettingsXML = new File(path + (path.endsWith("/") ? "settings_temp.xml" : "/settings_temp.xml"));
         if (settingsXML.canRead() && !tempSettingsXML.exists()) {
             tempSettingsXML.createNewFile();
 
-            final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
-            final DocumentBuilder builder = dbf.newDocumentBuilder();
+            DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
+            DOMImplementationLS domImpl = (DOMImplementationLS) reg.getDOMImplementation("LS");
+            LSInput lsinput = domImpl.createLSInput();
+            lsinput.setByteStream(new FileInputStream(settingsXML));
+            LSParser parser = domImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
             // parse settings.xml
-            final Document settings = builder.parse(settingsXML);
+            final Document settings = parser.parse(lsinput);
 
             final Element proxies = (Element) settings.getDocumentElement().getElementsByTagName("proxies").item(0);