VYPR
Moderate severityNVD Advisory· Published Aug 18, 2023· Updated Feb 13, 2025

Apache NiFi: Incomplete Validation of JDBC and JNDI Connection URLs

CVE-2023-40037

Description

Apache NiFi 1.21.0 through 1.23.0 support JDBC and JNDI JMS access in several Processors and Controller Services with connection URL validation that does not provide sufficient protection against crafted inputs. An authenticated and authorized user can bypass connection URL validation using custom input formatting. The resolution enhances connection URL validation and introduces validation for additional related properties. Upgrading to Apache NiFi 1.23.1 is the recommended mitigation.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache NiFi 1.21.0–1.23.0 allows authenticated users to bypass connection URL validation in JDBC/JNDI JMS components, enabling craftable inputs that subvert security checks.

Root

Cause Apache NiFi versions 1.21.0 through 1.23.0 include several Processors and Controller Services that support JDBC and JNDI JMS access. These components perform connection URL validation that is insufficient to protect against specially crafted inputs. The vulnerability arises because the validation logic does not account for custom input formatting that can be used to bypass the intended checks, as described in the official CVE description [1][2].

Exploitation

To exploit this flaw, an attacker must be an authenticated and authorized user of the Apache NiFi instance. The attacker can then supply a malformed or specially formatted connection URL to one of the affected processors or controller services. The insufficient validation allows the crafted input to be accepted, bypassing the intended security restrictions [1][2]. The vulnerability is specific to the connection property validation; no other authentication or network position is required beyond normal user access.

Impact

By bypassing the connection URL validation, an attacker could potentially connect to unauthorized or unexpected JDBC or JNDI resources, such as internal databases or messaging systems, that were not intended to be accessible via NiFi. This could lead to data exfiltration, unauthorized data access, or further internal network reconnaissance, depending on the configuration of the target environment [1][2]. No code execution or privilege escalation is implied by the CVE description.

Mitigation

The recommended mitigation is to upgrade to Apache NiFi version 1.23.1, which enhances the connection URL validation logic and introduces validation for additional related properties [1][2]. The fix is tracked in Jira as NIFI-11920 [4]. Users of earlier affected versions should upgrade as soon as possible to prevent exploitation.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.nifi:nifi-dbcp-baseMaven
>= 1.21.0, < 1.23.11.23.1
org.apache.nifi:nifi-jms-processorsMaven
>= 1.21.0, < 1.23.11.23.1
org.apache.nifi:nifi-dbcp-service-apiMaven
>= 1.21.0, < 1.23.11.23.1
org.apache.nifi:nifi-dbcp-service-bundleMaven
>= 1.21.0, < 1.23.11.23.1

Affected products

6

Patches

1
064550aacc18

NIFI-11920 Improved JDBC and JNDI JMS Connection URL Validation

https://github.com/apache/nifiexceptionfactoryAug 8, 2023via ghsa
8 files changed · +207 9
  • nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DBCPProperties.java+2 1 modified
    @@ -22,6 +22,7 @@
     import org.apache.nifi.components.resource.ResourceType;
     import org.apache.nifi.dbcp.ConnectionUrlValidator;
     import org.apache.nifi.dbcp.DBCPValidator;
    +import org.apache.nifi.dbcp.DriverClassValidator;
     import org.apache.nifi.expression.ExpressionLanguageScope;
     import org.apache.nifi.kerberos.KerberosUserService;
     import org.apache.nifi.processor.util.StandardValidators;
    @@ -67,7 +68,7 @@ private DBCPProperties() {
                 .description("Database driver class name")
                 .defaultValue(null)
                 .required(true)
    -            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
    +            .addValidator(new DriverClassValidator())
                 .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
                 .build();
     
    
  • nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JndiJmsConnectionFactoryProperties.java+5 3 modified
    @@ -158,10 +158,11 @@ static class JndiJmsProviderUrlValidator implements Validator {
             public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
                 final ValidationResult.Builder builder = new ValidationResult.Builder().subject(subject).input(input);
     
    -            if (input == null || input.isEmpty()) {
    +            final String url = context.newPropertyValue(input).evaluateAttributeExpressions().getValue();
    +            if (url == null || url.isEmpty()) {
                     builder.valid(false);
                     builder.explanation("URL is required");
    -            } else if (isUrlAllowed(input)) {
    +            } else if (isUrlAllowed(url)) {
                     builder.valid(true);
                     builder.explanation("URL scheme allowed");
                 } else {
    @@ -176,7 +177,8 @@ public ValidationResult validate(final String subject, final String input, final
             private boolean isUrlAllowed(final String input) {
                 final boolean allowed;
     
    -            final Matcher matcher = URL_SCHEME_PATTERN.matcher(input);
    +            final String normalizedUrl = input.trim();
    +            final Matcher matcher = URL_SCHEME_PATTERN.matcher(normalizedUrl);
                 if (matcher.matches()) {
                     final String scheme = matcher.group(SCHEME_GROUP);
                     allowed = isSchemeAllowed(scheme);
    
  • nifi-nar-bundles/nifi-jms-bundle/nifi-jms-processors/src/test/java/org/apache/nifi/jms/cf/JndiJmsConnectionFactoryProviderTest.java+22 1 modified
    @@ -41,6 +41,10 @@ public class JndiJmsConnectionFactoryProviderTest {
     
         private static final String LDAP_PROVIDER_URL = "ldap://127.0.0.1";
     
    +    private static final String LDAP_PROVIDER_URL_SPACED = String.format(" %s", LDAP_PROVIDER_URL);
    +
    +    private static final String LDAP_PROVIDER_URL_EXPRESSION = "ldap:${separator}//127.0.0.1";
    +
         private static final String HOST_PORT_URL = "127.0.0.1:1024";
     
         private static final String LDAP_ALLOWED_URL_SCHEMES = "ldap";
    @@ -81,6 +85,24 @@ void testPropertiesInvalidUrlScheme() {
             runner.assertNotValid(provider);
         }
     
    +    @Test
    +    void testPropertiesInvalidUrlSchemeSpaced() {
    +        setFactoryProperties();
    +
    +        runner.setProperty(provider, JndiJmsConnectionFactoryProperties.JNDI_PROVIDER_URL, LDAP_PROVIDER_URL_SPACED);
    +
    +        runner.assertNotValid(provider);
    +    }
    +
    +    @Test
    +    void testPropertiesInvalidUrlSchemeExpression() {
    +        setFactoryProperties();
    +
    +        runner.setProperty(provider, JndiJmsConnectionFactoryProperties.JNDI_PROVIDER_URL, LDAP_PROVIDER_URL_EXPRESSION);
    +
    +        runner.assertNotValid(provider);
    +    }
    +
         @Test
         void testPropertiesHostPortUrl() {
             setFactoryProperties();
    @@ -90,7 +112,6 @@ void testPropertiesHostPortUrl() {
             runner.assertValid(provider);
         }
     
    -
         @Test
         void testUrlSchemeValidSystemProperty() {
             try {
    
  • nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/ConnectionUrlValidator.java+3 3 modified
    @@ -37,11 +37,11 @@ public ValidationResult validate(final String subject, final String input, final
                 builder.valid(false);
                 builder.explanation("Connection URL required");
             } else {
    -            final String url = context.newPropertyValue(input).evaluateAttributeExpressions().getValue();
    +            final String url = context.newPropertyValue(input).evaluateAttributeExpressions().getValue().trim();
     
                 if (isUrlUnsupported(url)) {
                     builder.valid(false);
    -                builder.explanation(String.format("Connection URL starts with an unsupported scheme %s", UNSUPPORTED_SCHEMES));
    +                builder.explanation(String.format("Connection URL contains an unsupported scheme %s", UNSUPPORTED_SCHEMES));
                 } else {
                     builder.valid(true);
                     builder.explanation("Connection URL is valid");
    @@ -55,7 +55,7 @@ private boolean isUrlUnsupported(final String url) {
             boolean unsupported = false;
     
             for (final String unsupportedScheme : UNSUPPORTED_SCHEMES) {
    -            if (url.startsWith(unsupportedScheme)) {
    +            if (url.contains(unsupportedScheme)) {
                     unsupported = true;
                     break;
                 }
    
  • nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/DriverClassValidator.java+57 0 added
    @@ -0,0 +1,57 @@
    +/*
    + * 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.dbcp;
    +
    +import org.apache.nifi.components.ValidationContext;
    +import org.apache.nifi.components.ValidationResult;
    +import org.apache.nifi.components.Validator;
    +
    +import java.util.Collections;
    +import java.util.Set;
    +
    +/**
    + * Database Driver Class Validator supports system attribute expressions and evaluates class names against unsupported values
    + */
    +public class DriverClassValidator implements Validator {
    +    private static final Set<String> UNSUPPORTED_CLASSES = Collections.singleton("org.h2.Driver");
    +
    +    @Override
    +    public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
    +        final ValidationResult.Builder builder = new ValidationResult.Builder().subject(subject).input(input);
    +
    +        if (input == null || input.isEmpty()) {
    +            builder.valid(false);
    +            builder.explanation("Driver Class required");
    +        } else {
    +            final String driverClass = context.newPropertyValue(input).evaluateAttributeExpressions().getValue().trim();
    +
    +            if (isDriverClassUnsupported(driverClass)) {
    +                builder.valid(false);
    +                builder.explanation(String.format("Driver Class is listed as unsupported %s", UNSUPPORTED_CLASSES));
    +            } else {
    +                builder.valid(true);
    +                builder.explanation("Driver Class is valid");
    +            }
    +        }
    +
    +        return builder.build();
    +    }
    +
    +    private boolean isDriverClassUnsupported(final String driverClass) {
    +        return UNSUPPORTED_CLASSES.contains(driverClass);
    +    }
    +}
    
  • nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/test/java/org/apache/nifi/dbcp/ConnectionUrlValidatorTest.java+20 0 modified
    @@ -37,6 +37,10 @@ class ConnectionUrlValidatorTest {
     
         private static final String UNSUPPORTED_URL = "jdbc:h2:file";
     
    +    private static final String UNSUPPORTED_URL_SPACED = String.format(" %s ", UNSUPPORTED_URL);
    +
    +    private static final String UNSUPPORTED_URL_EXPRESSION = String.format("${attribute}%s", UNSUPPORTED_URL);
    +
         private static final String VENDOR_URL = "jdbc:vendor";
     
         private ValidationContext validationContext;
    @@ -67,6 +71,22 @@ void testValidateUnsupportedUrl() {
             assertFalse(result.isValid());
         }
     
    +    @Test
    +    void testValidateUnsupportedUrlExpressionLanguage() {
    +        final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_URL_EXPRESSION, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
    +    @Test
    +    void testValidateUnsupportedUrlSpaced() {
    +        final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_URL_SPACED, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
         @Test
         void testValidateSupportedUrl() {
             final ValidationResult result = validator.validate(SUBJECT, VENDOR_URL, validationContext);
    
  • nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/test/java/org/apache/nifi/dbcp/DriverClassValidatorTest.java+97 0 added
    @@ -0,0 +1,97 @@
    +/*
    + * 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.dbcp;
    +
    +import org.apache.nifi.components.ValidationContext;
    +import org.apache.nifi.components.ValidationResult;
    +import org.apache.nifi.util.MockProcessContext;
    +import org.apache.nifi.util.MockValidationContext;
    +import org.apache.nifi.util.NoOpProcessor;
    +import org.apache.nifi.util.TestRunners;
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Test;
    +
    +import static org.junit.jupiter.api.Assertions.assertFalse;
    +import static org.junit.jupiter.api.Assertions.assertNotNull;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +class DriverClassValidatorTest {
    +
    +    private static final String SUBJECT = "Database Driver Class";
    +
    +    private static final String EMPTY = "";
    +
    +    private static final String UNSUPPORTED_DRIVER = "org.h2.Driver";
    +
    +    private static final String UNSUPPORTED_DRIVER_SPACED = String.format(" %s ", UNSUPPORTED_DRIVER);
    +
    +    private static final String UNSUPPORTED_DRIVER_EXPRESSION = String.format("${attribute}%s", UNSUPPORTED_DRIVER);
    +
    +    private static final String OTHER_DRIVER = "org.apache.nifi.Driver";
    +
    +    private ValidationContext validationContext;
    +
    +    private DriverClassValidator validator;
    +
    +    @BeforeEach
    +    void setValidator() {
    +        validator = new DriverClassValidator();
    +
    +        final MockProcessContext processContext = (MockProcessContext) TestRunners.newTestRunner(NoOpProcessor.class).getProcessContext();
    +        validationContext = new MockValidationContext(processContext);
    +    }
    +
    +    @Test
    +    void testValidateEmpty() {
    +        final ValidationResult result = validator.validate(SUBJECT, EMPTY, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
    +    @Test
    +    void testValidateUnsupportedDriver() {
    +        final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_DRIVER, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
    +    @Test
    +    void testValidateUnsupportedDriverExpressionLanguage() {
    +        final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_DRIVER_EXPRESSION, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
    +    @Test
    +    void testValidateUnsupportedDriverSpaced() {
    +        final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_DRIVER_SPACED, validationContext);
    +
    +        assertNotNull(result);
    +        assertFalse(result.isValid());
    +    }
    +
    +    @Test
    +    void testValidateSupportedDriver() {
    +        final ValidationResult result = validator.validate(SUBJECT, OTHER_DRIVER, validationContext);
    +
    +        assertNotNull(result);
    +        assertTrue(result.isValid());
    +    }
    +}
    
  • nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-hikari-dbcp-service/src/main/java/org/apache/nifi/dbcp/HikariCPConnectionPool.java+1 1 modified
    @@ -98,7 +98,7 @@ public class HikariCPConnectionPool extends AbstractControllerService implements
                 .description("The fully-qualified class name of the JDBC driver. Example: com.mysql.jdbc.Driver")
                 .defaultValue(null)
                 .required(true)
    -            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
    +            .addValidator(new DriverClassValidator())
                 .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
                 .build();
     
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.