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

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


The following commit(s) were added to refs/heads/main by this push:
     new 5daabcd0e8 [MINOR] fix(catalog): block H2 JDBC URL and driver in 
catalog datasource creation (#10801)
5daabcd0e8 is described below

commit 5daabcd0e8ddc96e25bd6c6ce7b153cdb311c3f2
Author: Jerry Shao <[email protected]>
AuthorDate: Mon Apr 20 19:37:06 2026 +0800

    [MINOR] fix(catalog): block H2 JDBC URL and driver in catalog datasource 
creation (#10801)
    
    ### What changes were proposed in this pull request?
    
    Block H2 JDBC URLs and H2 driver class names in
    `DataSourceUtils.createDataSource()`, which is the entry point for all
    user-facing catalog JDBC connections.
    
    The check is intentionally scoped to `DataSourceUtils` and not added to
    the shared `JdbcUrlUtils.validateJdbcConfig()`, because that utility is
    also called by the internal entity store (`SqlSessionFactoryHelper`)
    which legitimately uses H2 as an embedded backend.
    
    ### Why are the changes needed?
    
    H2 is only used as an embedded backend for Gravitino's internal entity
    store and should not be used through user-facing catalog configuration.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Catalog creation or `testConnection` calls that supply an H2 JDBC URL
    (e.g. `jdbc:h2:...`) or H2 driver class (e.g. `org.h2.Driver`) will now
    be rejected with a clear error message. The check is case-insensitive.
    
    ### How was this patch tested?
    
    Added 4 tests to `TestDataSourceUrlValidation`:
    - `testRejectH2Url` — blocks H2 URL
    - `testRejectH2UrlCaseInsensitive` — blocks `JDBC:H2:...` (uppercase)
    - `testRejectH2Driver` — blocks `org.h2.Driver` with a non-H2 URL
    - `testRejectH2DriverCaseInsensitive` — blocks `ORG.H2.DRIVER`
    
    Co-authored-by: Claude Sonnet 4.6 <[email protected]>
---
 .../catalog/jdbc/utils/DataSourceUtils.java        | 11 ++++
 .../jdbc/utils/TestDataSourceUrlValidation.java    | 63 ++++++++++++++++++++++
 .../org/apache/gravitino/utils/JdbcUrlUtils.java   |  1 -
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git 
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/utils/DataSourceUtils.java
 
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/utils/DataSourceUtils.java
index 59da59b770..a2b8e12b80 100644
--- 
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/utils/DataSourceUtils.java
+++ 
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/utils/DataSourceUtils.java
@@ -45,6 +45,17 @@ public class DataSourceUtils {
 
   public static DataSource createDataSource(JdbcConfig jdbcConfig)
       throws GravitinoRuntimeException {
+    // H2 is bundled as an embedded backend and must not be used through 
user-facing catalog
+    // configuration. Its INIT parameter allows arbitrary SQL (and Java code 
via CREATE ALIAS)
+    // to execute at connection time, and the H2 driver class must also be 
blocked to prevent
+    // bypassing this check via a mismatched driver and URL combination.
+    String decodedUrl = recursiveDecode(jdbcConfig.getJdbcUrl().toLowerCase());
+    if (decodedUrl.startsWith("jdbc:h2")) {
+      throw new GravitinoRuntimeException("H2 JDBC URL is not allowed in 
catalog configuration");
+    }
+    if (jdbcConfig.getJdbcDriver().toLowerCase().startsWith("org.h2.")) {
+      throw new GravitinoRuntimeException("H2 JDBC driver is not allowed in 
catalog configuration");
+    }
     try {
       return createDBCPDataSource(jdbcConfig);
     } catch (Exception exception) {
diff --git 
a/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/TestDataSourceUrlValidation.java
 
b/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/TestDataSourceUrlValidation.java
index a8a98b5faa..e05e4f1062 100644
--- 
a/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/TestDataSourceUrlValidation.java
+++ 
b/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/TestDataSourceUrlValidation.java
@@ -84,4 +84,67 @@ public class TestDataSourceUrlValidation {
     Assertions.assertThrows(
         GravitinoRuntimeException.class, () -> 
DataSourceUtils.createDataSource(properties));
   }
+
+  @Test
+  public void testRejectH2Url() {
+    HashMap<String, String> properties = Maps.newHashMap();
+    properties.put(JdbcConfig.JDBC_DRIVER.getKey(), "org.postgresql.Driver");
+    properties.put(
+        JdbcConfig.JDBC_URL.getKey(),
+        "jdbc:h2:mem:test;INIT=CREATE ALIAS EXEC AS 'String f() throws 
Exception"
+            + " { Runtime.getRuntime().exec(\"id\"); return \"ok\"; }'\\;CALL 
EXEC()");
+    properties.put(JdbcConfig.USERNAME.getKey(), "test");
+    properties.put(JdbcConfig.PASSWORD.getKey(), "test");
+
+    GravitinoRuntimeException gre =
+        Assertions.assertThrows(
+            GravitinoRuntimeException.class, () -> 
DataSourceUtils.createDataSource(properties));
+    Assertions.assertEquals(
+        "H2 JDBC URL is not allowed in catalog configuration", 
gre.getMessage());
+  }
+
+  @Test
+  public void testRejectH2UrlCaseInsensitive() {
+    HashMap<String, String> properties = Maps.newHashMap();
+    properties.put(JdbcConfig.JDBC_DRIVER.getKey(), "org.postgresql.Driver");
+    properties.put(JdbcConfig.JDBC_URL.getKey(), "JDBC:H2:mem:test");
+    properties.put(JdbcConfig.USERNAME.getKey(), "test");
+    properties.put(JdbcConfig.PASSWORD.getKey(), "test");
+
+    GravitinoRuntimeException gre =
+        Assertions.assertThrows(
+            GravitinoRuntimeException.class, () -> 
DataSourceUtils.createDataSource(properties));
+    Assertions.assertEquals(
+        "H2 JDBC URL is not allowed in catalog configuration", 
gre.getMessage());
+  }
+
+  @Test
+  public void testRejectH2Driver() {
+    HashMap<String, String> properties = Maps.newHashMap();
+    properties.put(JdbcConfig.JDBC_DRIVER.getKey(), "org.h2.Driver");
+    properties.put(JdbcConfig.JDBC_URL.getKey(), 
"jdbc:postgresql://localhost:5432/test");
+    properties.put(JdbcConfig.USERNAME.getKey(), "test");
+    properties.put(JdbcConfig.PASSWORD.getKey(), "test");
+
+    GravitinoRuntimeException gre =
+        Assertions.assertThrows(
+            GravitinoRuntimeException.class, () -> 
DataSourceUtils.createDataSource(properties));
+    Assertions.assertEquals(
+        "H2 JDBC driver is not allowed in catalog configuration", 
gre.getMessage());
+  }
+
+  @Test
+  public void testRejectH2DriverCaseInsensitive() {
+    HashMap<String, String> properties = Maps.newHashMap();
+    properties.put(JdbcConfig.JDBC_DRIVER.getKey(), "ORG.H2.DRIVER");
+    properties.put(JdbcConfig.JDBC_URL.getKey(), 
"jdbc:postgresql://localhost:5432/test");
+    properties.put(JdbcConfig.USERNAME.getKey(), "test");
+    properties.put(JdbcConfig.PASSWORD.getKey(), "test");
+
+    GravitinoRuntimeException gre =
+        Assertions.assertThrows(
+            GravitinoRuntimeException.class, () -> 
DataSourceUtils.createDataSource(properties));
+    Assertions.assertEquals(
+        "H2 JDBC driver is not allowed in catalog configuration", 
gre.getMessage());
+  }
 }
diff --git a/common/src/main/java/org/apache/gravitino/utils/JdbcUrlUtils.java 
b/common/src/main/java/org/apache/gravitino/utils/JdbcUrlUtils.java
index 04dab3e1dc..e157109f1b 100644
--- a/common/src/main/java/org/apache/gravitino/utils/JdbcUrlUtils.java
+++ b/common/src/main/java/org/apache/gravitino/utils/JdbcUrlUtils.java
@@ -76,7 +76,6 @@ public class JdbcUrlUtils {
     String lowerUrl = url.toLowerCase();
     String decodedUrl = recursiveDecode(lowerUrl);
 
-    // As H2 is only used for testing, we do not check unsafe parameters for 
H2.
     if (decodedUrl.startsWith("jdbc:mysql")) {
       checkUnsafeParameters(decodedUrl, all, UNSAFE_MYSQL_PARAMETERS, "MySQL");
     } else if (decodedUrl.startsWith("jdbc:mariadb")) {

Reply via email to