diff --git a/nifi-commons/nifi-security-utils/pom.xml b/nifi-commons/nifi-security-utils/pom.xml
index 5c9acc3c2c..3f4a088f23 100644
--- a/nifi-commons/nifi-security-utils/pom.xml
+++ b/nifi-commons/nifi-security-utils/pom.xml
@@ -60,5 +60,18 @@
nifi-properties
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+
+
+ src/test/resources/xxe_template.xml
+
+
+
+
+
diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/xml/XmlUtils.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/xml/XmlUtils.java
new file mode 100644
index 0000000000..99c90a6d53
--- /dev/null
+++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/xml/XmlUtils.java
@@ -0,0 +1,44 @@
+/*
+ * 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.nifi.security.xml;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stream.StreamSource;
+import java.io.InputStream;
+
+public class XmlUtils {
+
+ public static XMLStreamReader createSafeReader(InputStream inputStream) throws XMLStreamException {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("The provided input stream cannot be null");
+ }
+ return createSafeReader(new StreamSource(inputStream));
+ }
+
+ public static XMLStreamReader createSafeReader(StreamSource source) throws XMLStreamException {
+ if (source == null) {
+ throw new IllegalArgumentException("The provided source cannot be null");
+ }
+
+ XMLInputFactory xif = XMLInputFactory.newFactory();
+ xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+ xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ return xif.createXMLStreamReader(source);
+ }
+}
diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/xml/XmlUtilsTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/xml/XmlUtilsTest.groovy
new file mode 100644
index 0000000000..6a1286fff2
--- /dev/null
+++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/xml/XmlUtilsTest.groovy
@@ -0,0 +1,96 @@
+/*
+ * 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.nifi.security.xml
+
+import org.junit.After
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import javax.xml.bind.JAXBContext
+import javax.xml.bind.UnmarshalException
+import javax.xml.bind.Unmarshaller
+import javax.xml.bind.annotation.XmlAccessType
+import javax.xml.bind.annotation.XmlAccessorType
+import javax.xml.bind.annotation.XmlAttribute
+import javax.xml.bind.annotation.XmlRootElement
+import javax.xml.stream.XMLStreamReader
+
+import static groovy.test.GroovyAssert.shouldFail
+
+@RunWith(JUnit4.class)
+class XmlUtilsTest {
+ private static final Logger logger = LoggerFactory.getLogger(XmlUtilsTest.class)
+
+ @BeforeClass
+ static void setUpOnce() throws Exception {
+ logger.metaClass.methodMissing = { String name, args ->
+ logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
+ }
+ }
+
+ @Before
+ void setUp() throws Exception {
+
+ }
+
+ @After
+ void tearDown() throws Exception {
+
+ }
+
+ @Test
+ void testShouldHandleXXEInUnmarshal() {
+ // Arrange
+ final String XXE_TEMPLATE_FILEPATH = "src/test/resources/xxe_template.xml"
+ InputStream templateStream = new File(XXE_TEMPLATE_FILEPATH).newInputStream()
+
+ JAXBContext context = JAXBContext.newInstance(XmlObject.class)
+
+ // Act
+ def msg = shouldFail(UnmarshalException) {
+ Unmarshaller unmarshaller = context.createUnmarshaller()
+ XMLStreamReader xsr = XmlUtils.createSafeReader(templateStream)
+ def parsed = unmarshaller.unmarshal(xsr, XmlObject.class)
+ logger.info("Unmarshalled ${parsed.toString()}")
+ }
+
+ // Assert
+ logger.expected(msg)
+ assert msg =~ "XMLStreamException: ParseError "
+ }
+}
+
+@XmlAccessorType( XmlAccessType.NONE )
+@XmlRootElement(name = "object")
+class XmlObject {
+ @XmlAttribute
+ String name
+
+ @XmlAttribute
+ String description
+
+ @XmlAttribute
+ String groupId
+
+ @XmlAttribute
+ String timestamp
+}
diff --git a/nifi-commons/nifi-security-utils/src/test/resources/xxe_template.xml b/nifi-commons/nifi-security-utils/src/test/resources/xxe_template.xml
new file mode 100644
index 0000000000..372d5070a1
--- /dev/null
+++ b/nifi-commons/nifi-security-utils/src/test/resources/xxe_template.xml
@@ -0,0 +1,7 @@
+]>
+
diff --git a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/cluster/ClusterNodeInformation.java b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/cluster/ClusterNodeInformation.java
index 1bc83b9a77..5a0264e4d4 100644
--- a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/cluster/ClusterNodeInformation.java
+++ b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/cluster/ClusterNodeInformation.java
@@ -19,13 +19,15 @@ package org.apache.nifi.remote.cluster;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.nifi.security.xml.XmlUtils;
@XmlRootElement
public class ClusterNodeInformation {
@@ -61,7 +63,12 @@ public class ClusterNodeInformation {
}
public static ClusterNodeInformation unmarshal(final InputStream is) throws JAXBException {
- final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- return (ClusterNodeInformation) unmarshaller.unmarshal(is);
+ try {
+ final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(is);
+ return (ClusterNodeInformation) unmarshaller.unmarshal(xsr);
+ } catch (XMLStreamException e) {
+ throw new JAXBException("Error unmarshalling the cluster node information", e);
+ }
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
index b0a64d98ea..41d23c00d8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/pom.xml
@@ -87,6 +87,10 @@
org.apache.nifi
nifi-framework-authorization
+
+ org.apache.nifi
+ nifi-security-utils
+
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
index fdc04a0c11..746c0eda1a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
@@ -16,31 +16,6 @@
*/
package org.apache.nifi.authorization;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authorization.annotation.AuthorizerContext;
-import org.apache.nifi.authorization.exception.AuthorizationAccessException;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
-import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.authorization.generated.Authorizers;
-import org.apache.nifi.authorization.generated.Property;
-import org.apache.nifi.bundle.Bundle;
-import org.apache.nifi.nar.ExtensionManager;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.util.file.classloader.ClassLoaderUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.xml.sax.SAXException;
-
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -51,6 +26,32 @@ import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.generated.Authorizers;
+import org.apache.nifi.authorization.generated.Property;
+import org.apache.nifi.bundle.Bundle;
+import org.apache.nifi.nar.ExtensionManager;
+import org.apache.nifi.security.xml.XmlUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.file.classloader.ClassLoaderUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.xml.sax.SAXException;
/**
* Factory bean for loading the configured authorizer.
@@ -168,9 +169,10 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, UserG
final Schema schema = schemaFactory.newSchema(Authorizers.class.getResource(AUTHORIZERS_XSD));
// attempt to unmarshal
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(new StreamSource(authorizersConfigurationFile));
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
unmarshaller.setSchema(schema);
- final JAXBElement element = unmarshaller.unmarshal(new StreamSource(authorizersConfigurationFile), Authorizers.class);
+ final JAXBElement element = unmarshaller.unmarshal(xsr, Authorizers.class);
return element.getValue();
} catch (SAXException | JAXBException e) {
throw new Exception("Unable to load the authorizer configuration file at: " + authorizersConfigurationFile.getAbsolutePath(), e);
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAccessPolicyProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAccessPolicyProvider.java
index 653a94997e..f71ad716c7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAccessPolicyProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAccessPolicyProvider.java
@@ -16,47 +16,6 @@
*/
package org.apache.nifi.authorization;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authorization.annotation.AuthorizerContext;
-import org.apache.nifi.authorization.exception.AuthorizationAccessException;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
-import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
-import org.apache.nifi.authorization.file.generated.Authorizations;
-import org.apache.nifi.authorization.file.generated.Policies;
-import org.apache.nifi.authorization.file.generated.Policy;
-import org.apache.nifi.authorization.resource.ResourceFactory;
-import org.apache.nifi.authorization.resource.ResourceType;
-import org.apache.nifi.authorization.util.IdentityMapping;
-import org.apache.nifi.authorization.util.IdentityMappingUtil;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.user.generated.Users;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.util.file.FileUtils;
-import org.apache.nifi.web.api.dto.PortDTO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
@@ -74,6 +33,48 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
+import org.apache.nifi.authorization.file.generated.Authorizations;
+import org.apache.nifi.authorization.file.generated.Policies;
+import org.apache.nifi.authorization.file.generated.Policy;
+import org.apache.nifi.authorization.resource.ResourceFactory;
+import org.apache.nifi.authorization.resource.ResourceType;
+import org.apache.nifi.authorization.util.IdentityMapping;
+import org.apache.nifi.authorization.util.IdentityMappingUtil;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.security.xml.XmlUtils;
+import org.apache.nifi.user.generated.Users;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.file.FileUtils;
+import org.apache.nifi.web.api.dto.PortDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
public class FileAccessPolicyProvider implements ConfigurableAccessPolicyProvider {
@@ -528,11 +529,17 @@ public class FileAccessPolicyProvider implements ConfigurableAccessPolicyProvide
}
private Authorizations unmarshallAuthorizations() throws JAXBException {
- final Unmarshaller unmarshaller = JAXB_AUTHORIZATIONS_CONTEXT.createUnmarshaller();
- unmarshaller.setSchema(authorizationsSchema);
+ try {
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(new StreamSource(authorizationsFile));
+ final Unmarshaller unmarshaller = JAXB_AUTHORIZATIONS_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(authorizationsSchema);
- final JAXBElement element = unmarshaller.unmarshal(new StreamSource(authorizationsFile), Authorizations.class);
- return element.getValue();
+ final JAXBElement element = unmarshaller.unmarshal(xsr, Authorizations.class);
+ return element.getValue();
+ } catch (XMLStreamException e) {
+ logger.error("Encountered an error reading authorizations file: ", e);
+ throw new JAXBException("Error reading authorizations file", e);
+ }
}
/**
@@ -626,8 +633,15 @@ public class FileAccessPolicyProvider implements ConfigurableAccessPolicyProvide
final Unmarshaller unmarshaller = JAXB_USERS_CONTEXT.createUnmarshaller();
unmarshaller.setSchema(usersSchema);
+ final XMLStreamReader xsr;
+ try {
+ xsr = XmlUtils.createSafeReader(new StreamSource(authorizedUsersFile));
+ } catch (XMLStreamException e) {
+ logger.error("Encountered an error reading authorized users file: ", e);
+ throw new JAXBException("Error reading authorized users file", e);
+ }
final JAXBElement element = unmarshaller.unmarshal(
- new StreamSource(authorizedUsersFile), org.apache.nifi.user.generated.Users.class);
+ xsr, org.apache.nifi.user.generated.Users.class);
final org.apache.nifi.user.generated.Users users = element.getValue();
if (users.getUser().isEmpty()) {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileUserGroupProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileUserGroupProvider.java
index 59c829c848..edcfa51420 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileUserGroupProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileUserGroupProvider.java
@@ -16,43 +16,6 @@
*/
package org.apache.nifi.authorization;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.authorization.annotation.AuthorizerContext;
-import org.apache.nifi.authorization.exception.AuthorizationAccessException;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
-import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
-import org.apache.nifi.authorization.file.tenants.generated.Groups;
-import org.apache.nifi.authorization.file.tenants.generated.Tenants;
-import org.apache.nifi.authorization.file.tenants.generated.Users;
-import org.apache.nifi.authorization.util.IdentityMapping;
-import org.apache.nifi.authorization.util.IdentityMappingUtil;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.util.file.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
@@ -70,6 +33,44 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.authorization.annotation.AuthorizerContext;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
+import org.apache.nifi.authorization.file.tenants.generated.Groups;
+import org.apache.nifi.authorization.file.tenants.generated.Tenants;
+import org.apache.nifi.authorization.file.tenants.generated.Users;
+import org.apache.nifi.authorization.util.IdentityMapping;
+import org.apache.nifi.authorization.util.IdentityMappingUtil;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.security.xml.XmlUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.file.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
public class FileUserGroupProvider implements ConfigurableUserGroupProvider {
@@ -665,8 +666,13 @@ public class FileUserGroupProvider implements ConfigurableUserGroupProvider {
final Unmarshaller unmarshaller = JAXB_TENANTS_CONTEXT.createUnmarshaller();
unmarshaller.setSchema(tenantsSchema);
- final JAXBElement element = unmarshaller.unmarshal(new StreamSource(tenantsFile), Tenants.class);
- return element.getValue();
+ try {
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(new StreamSource(tenantsFile));
+ final JAXBElement element = unmarshaller.unmarshal(xsr, Tenants.class);
+ return element.getValue();
+ } catch (XMLStreamException e) {
+ throw new JAXBException("Error unmarshalling tenants", e);
+ }
}
private void populateInitialUsers(final Tenants tenants) {
@@ -688,11 +694,18 @@ public class FileUserGroupProvider implements ConfigurableUserGroupProvider {
throw new AuthorizerCreationException("Legacy Authorized Users File '" + legacyAuthorizedUsersFile + "' does not exists");
}
+ XMLStreamReader xsr;
+ try {
+ xsr = XmlUtils.createSafeReader(new StreamSource(authorizedUsersFile));
+ } catch (XMLStreamException e) {
+ throw new AuthorizerCreationException("Error converting the legacy authorizers file", e);
+ }
+
final Unmarshaller unmarshaller = JAXB_USERS_CONTEXT.createUnmarshaller();
unmarshaller.setSchema(usersSchema);
final JAXBElement element = unmarshaller.unmarshal(
- new StreamSource(authorizedUsersFile), org.apache.nifi.user.generated.Users.class);
+ xsr, org.apache.nifi.user.generated.Users.class);
final org.apache.nifi.user.generated.Users users = element.getValue();
if (users.getUser().isEmpty()) {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/HeartbeatPayload.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/HeartbeatPayload.java
index 8363a20134..20848be599 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/HeartbeatPayload.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/HeartbeatPayload.java
@@ -21,14 +21,15 @@ import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
-
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
+import org.apache.nifi.security.xml.XmlUtils;
/**
* The payload of the heartbeat. The payload contains status to inform the cluster manager the current workload of this node.
@@ -111,18 +112,14 @@ public class HeartbeatPayload {
public static HeartbeatPayload unmarshal(final InputStream is) throws ProtocolException {
try {
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- return (HeartbeatPayload) unmarshaller.unmarshal(is);
- } catch (final JAXBException je) {
- throw new ProtocolException(je);
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(is);
+ return (HeartbeatPayload) unmarshaller.unmarshal(xsr);
+ } catch (final JAXBException | XMLStreamException e) {
+ throw new ProtocolException(e);
}
}
public static HeartbeatPayload unmarshal(final byte[] bytes) throws ProtocolException {
- try {
- final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- return (HeartbeatPayload) unmarshaller.unmarshal(new ByteArrayInputStream(bytes));
- } catch (final JAXBException je) {
- throw new ProtocolException(je);
- }
+ return unmarshal(new ByteArrayInputStream(bytes));
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/JaxbProtocolContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/JaxbProtocolContext.java
index 4d44b4e86a..23d45d11f5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/JaxbProtocolContext.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/jaxb/JaxbProtocolContext.java
@@ -25,15 +25,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
-
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import org.apache.nifi.cluster.protocol.ProtocolContext;
import org.apache.nifi.cluster.protocol.ProtocolMessageMarshaller;
import org.apache.nifi.cluster.protocol.ProtocolMessageUnmarshaller;
+import org.apache.nifi.security.xml.XmlUtils;
/**
* Implements a context for communicating internally amongst the cluster using
@@ -135,10 +136,11 @@ public class JaxbProtocolContext implements ProtocolContext {
final Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
final byte[] msg = new byte[totalBytesRead];
buffer.get(msg);
- return (T) unmarshaller.unmarshal(new ByteArrayInputStream(msg));
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(new ByteArrayInputStream(msg));
+ return (T) unmarshaller.unmarshal(xsr);
- } catch (final JAXBException je) {
- throw new IOException("Failed unmarshalling protocol message due to: " + je, je);
+ } catch (final JAXBException | XMLStreamException e) {
+ throw new IOException("Failed unmarshalling protocol message due to: " + e, e);
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/ClusterProtocolHeartbeatMonitor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/ClusterProtocolHeartbeatMonitor.java
index 78ec8dffe9..2d6f02327e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/ClusterProtocolHeartbeatMonitor.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/ClusterProtocolHeartbeatMonitor.java
@@ -16,6 +16,16 @@
*/
package org.apache.nifi.cluster.coordination.heartbeat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
import org.apache.nifi.cluster.coordination.node.NodeConnectionState;
import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus;
@@ -36,19 +46,6 @@ import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
/**
* Uses Apache ZooKeeper to advertise the address to send heartbeats to, and
* then relies on the NiFi Cluster Protocol to receive heartbeat messages from
@@ -63,17 +60,6 @@ public class ClusterProtocolHeartbeatMonitor extends AbstractHeartbeatMonitor im
private volatile long purgeTimestamp = System.currentTimeMillis();
- protected static final Unmarshaller nodeIdentifierUnmarshaller;
-
- static {
- try {
- final JAXBContext jaxbContext = JAXBContext.newInstance(NodeIdentifier.class);
- nodeIdentifierUnmarshaller = jaxbContext.createUnmarshaller();
- } catch (final Exception e) {
- throw new RuntimeException("Failed to create an Unmarshaller for unmarshalling Node Identifier", e);
- }
- }
-
public ClusterProtocolHeartbeatMonitor(final ClusterCoordinator clusterCoordinator, final ProtocolListener protocolListener, final NiFiProperties nifiProperties) {
super(clusterCoordinator, nifiProperties);
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/BulletinsPayload.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/BulletinsPayload.java
index 77d66205dc..e8a33a5b55 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/BulletinsPayload.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/cluster/BulletinsPayload.java
@@ -27,9 +27,12 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import org.apache.nifi.cluster.protocol.ProtocolException;
import org.apache.nifi.jaxb.BulletinAdapter;
import org.apache.nifi.reporting.Bulletin;
+import org.apache.nifi.security.xml.XmlUtils;
/**
* The payload of the bulletins.
@@ -77,18 +80,14 @@ public class BulletinsPayload {
public static BulletinsPayload unmarshal(final InputStream is) throws ProtocolException {
try {
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- return (BulletinsPayload) unmarshaller.unmarshal(is);
- } catch (final JAXBException je) {
- throw new ProtocolException(je);
+ final XMLStreamReader xsr = XmlUtils.createSafeReader(is);
+ return (BulletinsPayload) unmarshaller.unmarshal(xsr);
+ } catch (final JAXBException | XMLStreamException e) {
+ throw new ProtocolException(e);
}
}
public static BulletinsPayload unmarshal(final byte[] bytes) throws ProtocolException {
- try {
- final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- return (BulletinsPayload) unmarshaller.unmarshal(new ByteArrayInputStream(bytes));
- } catch (final JAXBException je) {
- throw new ProtocolException(je);
- }
+ return unmarshal(new ByteArrayInputStream(bytes));
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
index be27c5e35d..9583bbb041 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
@@ -18,7 +18,6 @@
package org.apache.nifi.controller;
import org.apache.nifi.persistence.TemplateDeserializer;
-import org.apache.nifi.stream.io.StreamUtils;
import org.apache.nifi.web.api.dto.ConnectableDTO;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
@@ -32,16 +31,15 @@ import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.TemplateDTO;
import org.w3c.dom.Element;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -49,9 +47,18 @@ public class TemplateUtils {
public static TemplateDTO parseDto(final Element templateElement) {
try {
- JAXBContext context = JAXBContext.newInstance(TemplateDTO.class);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- return unmarshaller.unmarshal(new DOMSource(templateElement), TemplateDTO.class).getValue();
+ final DOMSource domSource = new DOMSource(templateElement);
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final StreamResult streamResult = new StreamResult(baos);
+
+ // need to stream the template element as the TemplateDeserializer.deserialize operation needs to re-parse
+ // in order to apply explicit properties on the XMLInputFactory
+ final TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ final Transformer transformer = transformerFactory.newTransformer();
+ transformer.transform(domSource, streamResult);
+
+ return parseDto(baos.toByteArray());
} catch (final Exception e) {
throw new RuntimeException("Could not parse XML as a valid template", e);
}
@@ -61,42 +68,10 @@ public class TemplateUtils {
try (final InputStream in = new ByteArrayInputStream(bytes)) {
return TemplateDeserializer.deserialize(in);
} catch (final IOException ioe) {
- throw new RuntimeException("Could not parse bytes as template", ioe); // won't happen because of the types of streams being used
+ throw new RuntimeException("Could not parse bytes as template", ioe);
}
}
- public static List parseTemplateStream(final byte[] bytes) {
- final List templates = new ArrayList<>();
-
- try (final InputStream rawIn = new ByteArrayInputStream(bytes);
- final DataInputStream in = new DataInputStream(rawIn)) {
-
- while (isMoreData(in)) {
- final int length = in.readInt();
- final byte[] buffer = new byte[length];
- StreamUtils.fillBuffer(in, buffer, true);
- final TemplateDTO dto = TemplateDeserializer.deserialize(new ByteArrayInputStream(buffer));
- templates.add(new Template(dto));
- }
- } catch (final IOException e) {
- throw new RuntimeException("Could not parse bytes", e); // won't happen because of the types of streams being used
- }
-
- return templates;
- }
-
-
- private static boolean isMoreData(final InputStream in) throws IOException {
- in.mark(1);
- final int nextByte = in.read();
- if (nextByte == -1) {
- return false;
- }
-
- in.reset();
- return true;
- }
-
/**
* Scrubs the template prior to persisting in order to remove fields that shouldn't be included or are unnecessary.
*
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/StandardSnippetDeserializer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/StandardSnippetDeserializer.java
index e5b4796d2d..9aba5104f1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/StandardSnippetDeserializer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/StandardSnippetDeserializer.java
@@ -17,15 +17,15 @@
package org.apache.nifi.persistence;
import java.io.InputStream;
-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import org.apache.nifi.controller.StandardSnippet;
import org.apache.nifi.controller.serialization.FlowSerializationException;
+import org.apache.nifi.security.xml.XmlUtils;
public class StandardSnippetDeserializer {
@@ -33,9 +33,10 @@ public class StandardSnippetDeserializer {
try {
JAXBContext context = JAXBContext.newInstance(StandardSnippet.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
- JAXBElement snippetElement = unmarshaller.unmarshal(new StreamSource(inStream), StandardSnippet.class);
+ XMLStreamReader xsr = XmlUtils.createSafeReader(inStream);
+ JAXBElement snippetElement = unmarshaller.unmarshal(xsr, StandardSnippet.class);
return snippetElement.getValue();
- } catch (final JAXBException e) {
+ } catch (final JAXBException | XMLStreamException e) {
throw new FlowSerializationException(e);
}
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/TemplateDeserializer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/TemplateDeserializer.java
index 27e90931bb..d79e9e797b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/TemplateDeserializer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/persistence/TemplateDeserializer.java
@@ -16,30 +16,29 @@
*/
package org.apache.nifi.persistence;
-import java.io.InputStream;
+import org.apache.nifi.controller.serialization.FlowSerializationException;
+import org.apache.nifi.security.xml.XmlUtils;
+import org.apache.nifi.web.api.dto.TemplateDTO;
+
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
-import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
-import org.apache.nifi.controller.serialization.FlowSerializationException;
-import org.apache.nifi.web.api.dto.TemplateDTO;
+import java.io.InputStream;
public class TemplateDeserializer {
public static TemplateDTO deserialize(final InputStream inStream) {
+ return deserialize(new StreamSource(inStream));
+ }
+
+ public static TemplateDTO deserialize(final StreamSource source) {
try {
JAXBContext context = JAXBContext.newInstance(TemplateDTO.class);
-
- // Manually constructing the XIF is necessary to prevent XXE attacks
- XMLInputFactory xif = XMLInputFactory.newFactory();
- xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
- xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
- XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(inStream));
-
+ XMLStreamReader xsr = XmlUtils.createSafeReader(source);
Unmarshaller unmarshaller = context.createUnmarshaller();
JAXBElement templateElement = unmarshaller.unmarshal(xsr, TemplateDTO.class);
return templateElement.getValue();
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/persistence/TemplateSerializerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/persistence/TemplateSerializerTest.java
index 8ddfdfec3a..1683cf7c8a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/persistence/TemplateSerializerTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/persistence/TemplateSerializerTest.java
@@ -27,12 +27,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-
+import javax.xml.stream.XMLStreamReader;
+import org.apache.nifi.security.xml.XmlUtils;
import org.apache.nifi.util.ComponentIdGenerator;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
@@ -65,11 +64,12 @@ public class TemplateSerializerTest {
origTemplate.setSnippet(snippet);
byte[] serTemplate = TemplateSerializer.serialize(origTemplate);
- // Deserialize Template into TemplateDTP
+ // Deserialize Template into TemplateDTO
ByteArrayInputStream in = new ByteArrayInputStream(serTemplate);
JAXBContext context = JAXBContext.newInstance(TemplateDTO.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
- JAXBElement templateElement = unmarshaller.unmarshal(new StreamSource(in), TemplateDTO.class);
+ XMLStreamReader xsr = XmlUtils.createSafeReader(in);
+ JAXBElement templateElement = unmarshaller.unmarshal(xsr, TemplateDTO.class);
TemplateDTO deserTemplate = templateElement.getValue();
// Modify deserialized template
@@ -98,7 +98,7 @@ public class TemplateSerializerTest {
diffList.addAll(new HistogramDiff().diff(RawTextComparator.DEFAULT, rt1, rt2));
ByteArrayOutputStream out = new ByteArrayOutputStream();
- try (DiffFormatter diff = new DiffFormatter(out);) {
+ try (DiffFormatter diff = new DiffFormatter(out)) {
diff.format(diffList, rt1, rt2);
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(out.toByteArray()), StandardCharsets.UTF_8));
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
index 2d769c94a9..57b76c4e6a 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java
@@ -48,6 +48,7 @@ import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.registry.variable.VariableRegistryUpdateRequest;
import org.apache.nifi.registry.variable.VariableRegistryUpdateStep;
import org.apache.nifi.remote.util.SiteToSiteRestApiClient;
+import org.apache.nifi.security.xml.XmlUtils;
import org.apache.nifi.util.BundleUtils;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.ResourceNotFoundException;
@@ -127,7 +128,7 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
+import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -3238,7 +3239,8 @@ public class ProcessGroupResource extends ApplicationResource {
try {
JAXBContext context = JAXBContext.newInstance(TemplateDTO.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
- JAXBElement templateElement = unmarshaller.unmarshal(new StreamSource(in), TemplateDTO.class);
+ XMLStreamReader xsr = XmlUtils.createSafeReader(in);
+ JAXBElement templateElement = unmarshaller.unmarshal(xsr, TemplateDTO.class);
template = templateElement.getValue();
} catch (JAXBException jaxbe) {
logger.warn("An error occurred while parsing a template.", jaxbe);
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
index 59f88c7d11..0edf44e955 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml
@@ -77,6 +77,10 @@
org.apache.nifi
nifi-web-utils
+
+ org.apache.nifi
+ nifi-security-utils
+
org.apache.nifi
nifi-framework-core
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
index 5c6cc01a08..53a4ecfe8e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/spring/LoginIdentityProviderFactoryBean.java
@@ -30,6 +30,7 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
@@ -54,6 +55,7 @@ import org.apache.nifi.properties.NiFiPropertiesLoader;
import org.apache.nifi.properties.SensitivePropertyProtectionException;
import org.apache.nifi.properties.SensitivePropertyProvider;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
+import org.apache.nifi.security.xml.XmlUtils;
import org.apache.nifi.util.NiFiProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -139,9 +141,10 @@ public class LoginIdentityProviderFactoryBean implements FactoryBean, Disposable
final Schema schema = schemaFactory.newSchema(LoginIdentityProviders.class.getResource(LOGIN_IDENTITY_PROVIDERS_XSD));
// attempt to unmarshal
+ XMLStreamReader xsr = XmlUtils.createSafeReader(new StreamSource(loginIdentityProvidersConfigurationFile));
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
unmarshaller.setSchema(schema);
- final JAXBElement element = unmarshaller.unmarshal(new StreamSource(loginIdentityProvidersConfigurationFile), LoginIdentityProviders.class);
+ final JAXBElement element = unmarshaller.unmarshal(xsr, LoginIdentityProviders.class);
return element.getValue();
} catch (SAXException | JAXBException e) {
throw new Exception("Unable to load the login identity provider configuration file at: " + loginIdentityProvidersConfigurationFile.getAbsolutePath());
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
index 2576df7edb..776d2100c3 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/pom.xml
@@ -23,4 +23,10 @@
org.apache.nifi
nifi-update-attribute-model
Data model for UpdateAttribute.
+
+
+ org.apache.nifi
+ nifi-security-utils
+
+
diff --git a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/src/main/java/org/apache/nifi/update/attributes/serde/CriteriaSerDe.java b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/src/main/java/org/apache/nifi/update/attributes/serde/CriteriaSerDe.java
index 0ad19cedbe..6ed0bed174 100644
--- a/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/src/main/java/org/apache/nifi/update/attributes/serde/CriteriaSerDe.java
+++ b/nifi-nar-bundles/nifi-update-attribute-bundle/nifi-update-attribute-model/src/main/java/org/apache/nifi/update/attributes/serde/CriteriaSerDe.java
@@ -16,8 +16,9 @@
*/
package org.apache.nifi.update.attributes.serde;
-import java.io.StringReader;
+import java.io.ByteArrayInputStream;
import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
@@ -25,8 +26,9 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.nifi.security.xml.XmlUtils;
import org.apache.nifi.update.attributes.Criteria;
import org.apache.nifi.update.attributes.FlowFilePolicy;
import org.apache.nifi.update.attributes.Rule;
@@ -119,14 +121,14 @@ public class CriteriaSerDe {
try {
// deserialize the binding
final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- final Source source = new StreamSource(new StringReader(string));
- final JAXBElement element = unmarshaller.unmarshal(source, CriteriaBinding.class);
+ XMLStreamReader xsr = XmlUtils.createSafeReader(new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8)));
+ final JAXBElement element = unmarshaller.unmarshal(xsr, CriteriaBinding.class);
// create the criteria from the binding
final CriteriaBinding binding = element.getValue();
criteria = new Criteria(binding.getFlowFilePolicy(), binding.getRules());
- } catch (final JAXBException jaxbe) {
- throw new IllegalArgumentException(jaxbe);
+ } catch (final JAXBException | XMLStreamException e) {
+ throw new IllegalArgumentException(e);
}
}