This is an automated email from the ASF dual-hosted git repository.

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 8011bf482c3 NIFI-5779 Applied Secure Processing in TransformXml to 
Sources
8011bf482c3 is described below

commit 8011bf482c3eaef56e9bfe78efadce37cc019c81
Author: exceptionfactory <[email protected]>
AuthorDate: Tue Mar 3 22:17:03 2026 -0600

    NIFI-5779 Applied Secure Processing in TransformXml to Sources
    
    This closes #10959.
    
    Signed-off-by: Pierre Villard <[email protected]>
---
 .../nifi/processors/standard/TransformXml.java     | 34 +++++++++++++++++-----
 .../nifi/processors/standard/TestTransformXml.java | 17 +++++++++--
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/TransformXml.java
 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/TransformXml.java
index 55e50a395fd..13e6e317d5b 100644
--- 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/TransformXml.java
+++ 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/TransformXml.java
@@ -184,8 +184,12 @@ public class TransformXml extends AbstractProcessor {
             REL_FAILURE
     );
 
+    private static final XMLStreamReaderProvider STREAM_READER_PROVIDER = new 
StandardXMLStreamReaderProvider();
+
     private LoadingCache<String, Templates> cache;
 
+    private volatile boolean secureProcessingEnabled;
+
     @Override
     public Set<Relationship> getRelationships() {
         return RELATIONSHIPS;
@@ -250,6 +254,8 @@ public class TransformXml extends AbstractProcessor {
 
     @OnScheduled
     public void onScheduled(final ProcessContext context) {
+        secureProcessingEnabled = 
context.getProperty(SECURE_PROCESSING).asBoolean();
+
         final ComponentLog logger = getLogger();
         final Integer cacheSize = context.getProperty(CACHE_SIZE).asInteger();
         final Long cacheTTL = 
context.getProperty(CACHE_TTL_AFTER_LAST_ACCESS).asTimePeriod(TimeUnit.SECONDS);
@@ -302,7 +308,7 @@ public class TransformXml extends AbstractProcessor {
                         }
                     }
 
-                    final Source source = new 
StreamSource(bufferedInputStream);
+                    final Source source = getSource(bufferedInputStream);
                     final Result result = new StreamResult(outputStream);
                     transformer.transform(source, result);
                 } catch (final Exception e) {
@@ -335,18 +341,17 @@ public class TransformXml extends AbstractProcessor {
 
     @SuppressWarnings("unchecked")
     private Templates newTemplates(final ProcessContext context, final String 
path) throws TransformerConfigurationException, LookupFailureException {
-        final boolean secureProcessing = 
context.getProperty(SECURE_PROCESSING).asBoolean();
-        final TransformerFactory transformerFactory = 
getTransformerFactory(secureProcessing);
+        final TransformerFactory transformerFactory = getTransformerFactory();
         final LookupService<String> lookupService = 
context.getProperty(XSLT_CONTROLLER).asControllerService(LookupService.class);
         final boolean filePath = context.getProperty(XSLT_FILE_NAME).isSet();
         final StreamSource templateSource = getTemplateSource(lookupService, 
path, filePath);
-        final Source configuredTemplateSource = secureProcessing ? 
getSecureSource(templateSource) : templateSource;
+        final Source configuredTemplateSource = secureProcessingEnabled ? 
getSecureSource(templateSource) : templateSource;
         return transformerFactory.newTemplates(configuredTemplateSource);
     }
 
-    private TransformerFactory getTransformerFactory(final boolean 
secureProcessing) throws TransformerConfigurationException {
+    private TransformerFactory getTransformerFactory() throws 
TransformerConfigurationException {
         final TransformerFactory factory = TransformerFactory.newInstance();
-        if (secureProcessing) {
+        if (secureProcessingEnabled) {
             factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
             
factory.setFeature("http://saxon.sf.net/feature/parserFeature?uri=http://xml.org/sax/features/external-parameter-entities";,
 false);
             
factory.setFeature("http://saxon.sf.net/feature/parserFeature?uri=http://xml.org/sax/features/external-general-entities";,
 false);
@@ -375,10 +380,23 @@ public class TransformXml extends AbstractProcessor {
         return streamSource;
     }
 
+    private Source getSource(final InputStream inputStream) {
+        final Source source;
+
+        final StreamSource streamSource = new StreamSource(inputStream);
+        if (secureProcessingEnabled) {
+            final XMLStreamReader streamReader = 
STREAM_READER_PROVIDER.getStreamReader(streamSource);
+            source = new StAXSource(streamReader);
+        } else {
+            source = streamSource;
+        }
+
+        return source;
+    }
+
     private Source getSecureSource(final StreamSource streamSource) throws 
TransformerConfigurationException {
-        final XMLStreamReaderProvider provider = new 
StandardXMLStreamReaderProvider();
         try {
-            final XMLStreamReader streamReader = 
provider.getStreamReader(streamSource);
+            final XMLStreamReader streamReader = 
STREAM_READER_PROVIDER.getStreamReader(streamSource);
             return new StAXSource(streamReader);
         } catch (final ProcessingException e) {
             throw new TransformerConfigurationException("XSLT Source Stream 
Reader creation failed", e);
diff --git 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestTransformXml.java
 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestTransformXml.java
index f6fae788a4b..4807d63bb8d 100644
--- 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestTransformXml.java
+++ 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestTransformXml.java
@@ -263,11 +263,12 @@ public class TestTransformXml {
     }
 
     @Test
-    public void testTransformSecureProcessingEnabledXmlWithEntity() {
+    public void 
testTransformSecureProcessingEnabledXmlWithDocumentTypeDefinition() {
         runner.setProperty(TransformXml.XSLT_FILE_NAME, 
"src/test/resources/TestTransformXml/doc-node.xsl");
         runner.setProperty(TransformXml.INDENT_OUTPUT, 
Boolean.FALSE.toString());
+        runner.setProperty(TransformXml.SECURE_PROCESSING, 
Boolean.TRUE.toString());
 
-        final String input = "<!DOCTYPE doc [<!ENTITY uri SYSTEM 
\"http://127.0.0.1\"; >]><doc>&uri;</doc>";
+        final String input = "<!DOCTYPE doc SYSTEM \"doc.dtd\"><doc></doc>";
         runner.enqueue(input);
         runner.run();
 
@@ -278,6 +279,18 @@ public class TestTransformXml {
         transformed.assertContentEquals(expected);
     }
 
+    @Test
+    public void testTransformSecureProcessingEnabledXmlWithEntity() {
+        runner.setProperty(TransformXml.XSLT_FILE_NAME, 
"src/test/resources/TestTransformXml/doc-node.xsl");
+        runner.setProperty(TransformXml.INDENT_OUTPUT, 
Boolean.FALSE.toString());
+
+        final String input = "<!DOCTYPE doc [<!ENTITY uri SYSTEM 
\"http://127.0.0.1\"; >]><doc>&uri;</doc>";
+        runner.enqueue(input);
+        runner.run();
+
+        runner.assertAllFlowFilesTransferred(TransformXml.REL_FAILURE);
+    }
+
     @Test
     public void testTransformSecureProcessingEnabledXslWithEntity() throws 
IOException {
         runner.setProperty(TransformXml.XSLT_FILE_NAME, 
"src/test/resources/TestTransformXml/doctype-entity-file-uri.xsl");

Reply via email to