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:16 UTC

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

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 63d5e2df8 -> 735579b6f
  refs/heads/master 1edec313d -> 7b168c142


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/ad31479c
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ad31479c
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ad31479c

Branch: refs/heads/2_0_X
Commit: ad31479c1c543ac7d26b8c882aa14f6c00c1fd0a
Parents: 63d5e2d
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 12:38:37 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      | 14 +++-
 .../jpa/content/XMLContentExporter.java         |  5 +-
 .../job/report/DefaultReportJobDelegate.java    | 20 +++++-
 .../java/utils/VoidURIResolver.java             | 35 ++++++++++
 .../core/logic/init/CamelRouteLoader.java       | 14 ++--
 .../core/logic/saml2/SAML2ReaderWriter.java     |  6 +-
 .../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 | 30 ++++-----
 16 files changed, 209 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/ad31479c/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/ad31479c/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/ad31479c/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/ad31479c/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/ad31479c/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 1d8c6e2..45617f3 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;
@@ -34,6 +34,7 @@ import org.apache.cocoon.pipeline.util.StringRepresentation;
 import org.apache.cocoon.sax.AbstractSAXTransformer;
 import org.apache.cocoon.sax.SAXConsumer;
 import org.apache.cocoon.sax.util.SAXConsumerAdapter;
+import org.apache.syncope.core.provisioning.java.utils.VoidURIResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -132,7 +133,7 @@ public class XSLTTransformer extends AbstractSAXTransformer implements CachingPi
         if (parameters == null) {
             this.parameters = null;
         } else {
-            this.parameters = new HashMap<String, Object>(parameters);
+            this.parameters = new HashMap<>(parameters);
         }
     }
 
@@ -183,7 +184,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(new VoidURIResolver());
+        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/ad31479c/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 f1f3e44..ea63d59 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
@@ -42,6 +42,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 import javax.sql.DataSource;
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
@@ -367,8 +368,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/ad31479c/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 232f93f..2bfa123 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;
@@ -44,6 +47,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.provisioning.api.job.report.ReportJobDelegate;
+import org.apache.syncope.core.provisioning.java.utils.VoidURIResolver;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -58,6 +62,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(new VoidURIResolver());
+        try {
+            TRANSFORMER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        } catch (TransformerConfigurationException e) {
+            LOG.error("Could not enable secure XML processing", e);
+        }
+    }
+
     /**
      * Report DAO.
      */
@@ -127,9 +143,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/ad31479c/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/VoidURIResolver.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/VoidURIResolver.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/VoidURIResolver.java
new file mode 100644
index 0000000..fcd5818
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/VoidURIResolver.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.utils;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+
+/**
+ * This implementation disallows any XSLT include, for security reasons.
+ */
+public class VoidURIResolver implements URIResolver {
+
+    @Override
+    public Source resolve(final String href, final String base) throws TransformerException {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/ad31479c/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..8317589 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;
@@ -37,6 +37,7 @@ import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
+import org.apache.syncope.core.provisioning.java.utils.VoidURIResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -153,11 +154,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(new VoidURIResolver());
+
+                    Document doc = StaxUtils.read(resource.getInputStream());
 
                     routeNodes = doc.getDocumentElement().getElementsByTagName("route");
                 } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/ad31479c/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 f711b56..b41fa76 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
@@ -50,6 +50,7 @@ import org.apache.syncope.common.lib.SSOConstants;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.common.lib.types.SignatureAlgorithm;
 import org.apache.syncope.core.logic.init.SAML2SPLoader;
+import org.apache.syncope.core.provisioning.java.utils.VoidURIResolver;
 import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.saml.OpenSAMLUtil;
@@ -77,6 +78,7 @@ public class SAML2ReaderWriter {
 
     static {
         TRANSFORMER_FACTORY = TransformerFactory.newInstance();
+        TRANSFORMER_FACTORY.setURIResolver(new VoidURIResolver());
         try {
             TRANSFORMER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
         } catch (TransformerConfigurationException e) {
@@ -103,14 +105,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/ad31479c/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 530a377..ea4bef5 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
@@ -54,6 +54,40 @@ import org.junit.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().getReportletConfs();
@@ -139,35 +173,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);
@@ -192,7 +197,7 @@ public class ReportITCase extends AbstractITCase {
         assertNotNull(reportTO);
 
         try {
-            execute(reportTO.getKey());
+            execReport(reportTO.getKey());
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.Scheduling, e.getType());
@@ -202,7 +207,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);
@@ -226,7 +231,7 @@ public class ReportITCase extends AbstractITCase {
         reportTO = createReport(reportTO);
         assertNotNull(reportTO);
 
-        String execKey = execute(reportTO.getKey());
+        String execKey = execReport(reportTO.getKey());
         assertNotNull(execKey);
 
         try {
@@ -266,7 +271,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/ad31479c/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 c0882ee..94ed959 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.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/ad31479c/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 8115b2b..5f0c41e 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/ad31479c/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 63668cf..1cf81d8 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/ad31479c/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/ad31479c/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 59ee898..58282fb 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,8 +20,8 @@ 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.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -34,11 +34,6 @@ import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
-
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
@@ -51,7 +46,10 @@ import org.apache.maven.shared.invoker.PrintStreamHandler;
 import org.apache.maven.shared.invoker.PrintStreamLogger;
 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 {
 
@@ -85,7 +83,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);
@@ -122,7 +120,7 @@ public class MavenUtils {
             try {
                 final MessageDigest cript = MessageDigest.getInstance("SHA-1");
                 String encodedPassword =
-                    new String(Hex.encodeHex(cript.digest(adminPassword.getBytes(StandardCharsets.UTF_8))));
+                        new String(Hex.encodeHex(cript.digest(adminPassword.getBytes(StandardCharsets.UTF_8))));
                 properties.setProperty("adminPassword", encodedPassword);
             } catch (final NoSuchAlgorithmException ex) {
                 Logger.getLogger(MavenUtils.class.getName()).log(Level.SEVERE, "NoSuchAlgorithmException", ex);
@@ -193,19 +191,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);
 


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

Posted by il...@apache.org.
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);
 


[2/4] syncope git commit: Review fields usable for search and orderBy

Posted by il...@apache.org.
Review fields usable for search and orderBy


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

Branch: refs/heads/2_0_X
Commit: 735579b6f987b407049ac1f1da08e675d957c3e6
Parents: ad31479
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Mar 7 12:21:21 2018 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Mar 9 14:56:22 2018 +0100

----------------------------------------------------------------------
 .../common/lib/search/SearchableFields.java      |  2 +-
 .../jpa/dao/AbstractAnySearchDAO.java            | 17 +++++++++++++++++
 .../persistence/jpa/dao/JPAAnySearchDAO.java     |  4 ++--
 .../jpa/dao/ElasticsearchAnySearchDAO.java       |  2 +-
 .../apache/syncope/fit/core/SearchITCase.java    | 19 +++++++++++++++++++
 5 files changed, 40 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/735579b6/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
index 5dbf149..77a7d13 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
@@ -36,7 +36,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 public final class SearchableFields {
 
     private static final String[] ATTRIBUTES_NOTINCLUDED = {
-        "serialVersionUID", "password", "type", "udynMembershipCond"
+        "serialVersionUID", "password", "type", "udynMembershipCond", "securityAnswer", "token", "tokenExpireTime"
     };
 
     private static final Set<String> ANY_FIELDS = new HashSet<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/735579b6/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
index c526a3c..229ecdf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -30,7 +30,10 @@ import javax.validation.ValidationException;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -68,6 +71,10 @@ import org.springframework.util.ReflectionUtils;
 
 public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO {
 
+    private static final String[] ORDER_BY_NOT_ALLOWED = {
+        "serialVersionUID", "password", "securityQuestion", "securityAnswer", "token", "tokenExpireTime"
+    };
+
     @Autowired
     protected RealmDAO realmDAO;
 
@@ -134,6 +141,16 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
         return search(SyncopeConstants.FULL_ADMIN_REALMS, cond, -1, -1, orderBy, kind);
     }
 
+    protected List<OrderByClause> filterOrderBy(final List<OrderByClause> orderBy) {
+        return ListUtils.select(orderBy, new Predicate<OrderByClause>() {
+
+            @Override
+            public boolean evaluate(final OrderByClause clause) {
+                return !ArrayUtils.contains(ORDER_BY_NOT_ALLOWED, clause.getField());
+            }
+        });
+    }
+
     protected abstract <T extends Any<?>> List<T> doSearch(
             Set<String> adminRealms,
             SearchCond searchCondition,

http://git-wip-us.apache.org/repos/asf/syncope/blob/735579b6/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 71d6c6c..f33295d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -276,13 +276,13 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
     }
 
     private OrderBySupport parseOrderBy(
-            final AnyTypeKind kind, final SearchSupport svs, final List<OrderByClause> orderByClauses) {
+            final AnyTypeKind kind, final SearchSupport svs, final List<OrderByClause> orderBy) {
 
         AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
 
         OrderBySupport obs = new OrderBySupport();
 
-        for (OrderByClause clause : orderByClauses) {
+        for (OrderByClause clause : filterOrderBy(orderBy)) {
             OrderBySupport.Item item = new OrderBySupport.Item();
 
             // Manage difference among external key attribute and internal JPA @Id

http://git-wip-us.apache.org/repos/asf/syncope/blob/735579b6/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
index 672a13f..bb37c3d 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
+++ b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
@@ -147,7 +147,7 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
 
         AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
 
-        for (OrderByClause clause : orderBy) {
+        for (OrderByClause clause : filterOrderBy(orderBy)) {
             String sortName = null;
 
             // Manage difference among external key attribute and internal JPA @Id

http://git-wip-us.apache.org/repos/asf/syncope/blob/735579b6/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index c8d9d97..4af22aa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -29,6 +29,7 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.patch.AnyObjectPatch;
@@ -407,6 +408,24 @@ public class SearchITCase extends AbstractITCase {
     }
 
     @Test
+    public void searchBySecurityAnswer() {
+        String securityAnswer = RandomStringUtils.randomAlphanumeric(10);
+        UserTO userTO = UserITCase.getUniqueSampleTO("securityAnswer@syncope.apache.org");
+        userTO.setSecurityQuestion("887028ea-66fc-41e7-b397-620d7ea6dfbb");
+        userTO.setSecurityAnswer(securityAnswer);
+
+        userTO = createUser(userTO).getEntity();
+        assertNotNull(userTO.getSecurityQuestion());
+
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("securityAnswer").equalTo(securityAnswer).query()).build());
+        assertNotNull(matchingUsers);
+        assertTrue(matchingUsers.getResult().isEmpty());
+    }
+
+    @Test
     public void assignable() {
         PagedResult<GroupTO> groups = groupService.search(new AnyQuery.Builder().realm("/even/two").page(1).size(1000).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().isAssignable().


[4/4] syncope git commit: Review fields usable for search and orderBy

Posted by il...@apache.org.
Review fields usable for search and orderBy


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

Branch: refs/heads/master
Commit: 7b168c142b09c3b03e39f1449211e7ddf026a14d
Parents: 717289b
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Mar 7 12:21:21 2018 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Mar 9 15:27:43 2018 +0100

----------------------------------------------------------------------
 .../common/lib/search/SearchableFields.java      |  2 +-
 .../jpa/dao/AbstractAnySearchDAO.java            | 11 +++++++++++
 .../persistence/jpa/dao/JPAAnySearchDAO.java     |  4 ++--
 .../apache/syncope/fit/core/SearchITCase.java    | 19 +++++++++++++++++++
 4 files changed, 33 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/7b168c14/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
index 5dbf149..77a7d13 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
@@ -36,7 +36,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 public final class SearchableFields {
 
     private static final String[] ATTRIBUTES_NOTINCLUDED = {
-        "serialVersionUID", "password", "type", "udynMembershipCond"
+        "serialVersionUID", "password", "type", "udynMembershipCond", "securityAnswer", "token", "tokenExpireTime"
     };
 
     private static final Set<String> ANY_FIELDS = new HashSet<>();

http://git-wip-us.apache.org/repos/asf/syncope/blob/7b168c14/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
index c8b27d2..178fa00 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -30,6 +30,7 @@ import javax.persistence.Entity;
 import javax.validation.ValidationException;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -67,6 +68,10 @@ import org.springframework.util.ReflectionUtils;
 
 public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO {
 
+    private static final String[] ORDER_BY_NOT_ALLOWED = {
+        "serialVersionUID", "password", "securityQuestion", "securityAnswer", "token", "tokenExpireTime"
+    };
+
     @Autowired
     protected RealmDAO realmDAO;
 
@@ -129,6 +134,12 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
         return search(SyncopeConstants.FULL_ADMIN_REALMS, cond, -1, -1, orderBy, kind);
     }
 
+    protected List<OrderByClause> filterOrderBy(final List<OrderByClause> orderBy) {
+        return orderBy.stream().
+                filter(clause -> !ArrayUtils.contains(ORDER_BY_NOT_ALLOWED, clause.getField())).
+                collect(Collectors.toList());
+    }
+
     protected abstract <T extends Any<?>> List<T> doSearch(
             Set<String> adminRealms,
             SearchCond searchCondition,

http://git-wip-us.apache.org/repos/asf/syncope/blob/7b168c14/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 0f0df60..7ffd176 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -276,13 +276,13 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
     }
 
     private OrderBySupport parseOrderBy(
-            final AnyTypeKind kind, final SearchSupport svs, final List<OrderByClause> orderByClauses) {
+            final AnyTypeKind kind, final SearchSupport svs, final List<OrderByClause> orderBy) {
 
         AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
 
         OrderBySupport obs = new OrderBySupport();
 
-        for (OrderByClause clause : orderByClauses) {
+        for (OrderByClause clause : filterOrderBy(orderBy)) {
             OrderBySupport.Item item = new OrderBySupport.Item();
 
             // Manage difference among external key attribute and internal JPA @Id

http://git-wip-us.apache.org/repos/asf/syncope/blob/7b168c14/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index 0677ad7..e159778 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.patch.AnyObjectPatch;
@@ -348,6 +349,24 @@ public class SearchITCase extends AbstractITCase {
     }
 
     @Test
+    public void searchBySecurityAnswer() {
+        String securityAnswer = RandomStringUtils.randomAlphanumeric(10);
+        UserTO userTO = UserITCase.getUniqueSampleTO("securityAnswer@syncope.apache.org");
+        userTO.setSecurityQuestion("887028ea-66fc-41e7-b397-620d7ea6dfbb");
+        userTO.setSecurityAnswer(securityAnswer);
+
+        userTO = createUser(userTO).getEntity();
+        assertNotNull(userTO.getSecurityQuestion());
+
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                        fiql(SyncopeClient.getUserSearchConditionBuilder().
+                                is("securityAnswer").equalTo(securityAnswer).query()).build());
+        assertNotNull(matchingUsers);
+        assertTrue(matchingUsers.getResult().isEmpty());
+    }
+
+    @Test
     public void assignable() {
         PagedResult<GroupTO> groups = groupService.search(new AnyQuery.Builder().realm("/even/two").page(1).size(1000).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().isAssignable().