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

kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new f1e7ae28e04 [Enhancement](jdbc catalog) Add security check on driver 
when creating Jdbc Catalog (#31153) (#31225)
f1e7ae28e04 is described below

commit f1e7ae28e04d0fd3ac1601a9b4f8a03d2bce1e5a
Author: zy-kkk <[email protected]>
AuthorDate: Wed Feb 21 20:48:13 2024 +0800

    [Enhancement](jdbc catalog) Add security check on driver when creating Jdbc 
Catalog (#31153) (#31225)
---
 .../main/java/org/apache/doris/common/Config.java  |  8 ++++++++
 .../org/apache/doris/catalog/JdbcResource.java     | 19 +++++++++++++++--
 .../doris/datasource/jdbc/JdbcExternalCatalog.java | 24 ++++++++++++++--------
 .../org/apache/doris/catalog/JdbcResourceTest.java | 15 ++++++++++++++
 4 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java 
b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java
index 7dda751e8f6..ff61b17ff32 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java
@@ -140,6 +140,14 @@ public class Config extends ConfigBase {
                     + "if the specified driver file path is not an absolute 
path, Doris will find jars from this path"})
     public static String jdbc_drivers_dir = System.getenv("DORIS_HOME") + 
"/jdbc_drivers";
 
+    @ConfField(description = {"JDBC 驱动的安全路径。在创建 JDBC Catalog 
时,允许使用的文件或者网络路径,可配置多个,使用分号分隔"
+            + "默认为 * 全部允许,如果设置为空责全部不允许",
+            "The safe path of the JDBC driver. When creating a JDBC Catalog,"
+                    + "you can configure multiple files or network paths that 
are allowed to be used,"
+                    + "separated by semicolons"
+                    + "The default is * to allow all, if set to empty, all are 
not allowed"})
+    public static String jdbc_driver_secure_path = "*";
+
     @ConfField(mutable = true, masterOnly = true, description = {"broker load 
时,单个节点上 load 执行计划的默认并行度",
             "The default parallelism of the load execution plan on a single 
node when the broker load is submitted"})
     public static int default_load_parallelism = 1;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
index c5b66e13f48..3291b64cbb0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
@@ -42,6 +42,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.util.Arrays;
 import java.util.Map;
 
 
@@ -275,14 +276,28 @@ public class JdbcResource extends Resource {
         }
     }
 
-    public static String getFullDriverUrl(String driverUrl) {
+    public static String getFullDriverUrl(String driverUrl) throws 
IllegalArgumentException {
         try {
             URI uri = new URI(driverUrl);
             String schema = uri.getScheme();
             if (schema == null && !driverUrl.startsWith("/")) {
                 return "file://" + Config.jdbc_drivers_dir + "/" + driverUrl;
+            } else {
+                if ("*".equals(Config.jdbc_driver_secure_path)) {
+                    return driverUrl;
+                } else if (Config.jdbc_driver_secure_path.trim().isEmpty()) {
+                    throw new IllegalArgumentException(
+                            "jdbc_driver_secure_path is set to empty, 
disallowing all driver URLs.");
+                } else {
+                    boolean isAllowed = 
Arrays.stream(Config.jdbc_driver_secure_path.split(";"))
+                            .anyMatch(allowedPath -> 
driverUrl.startsWith(allowedPath.trim()));
+                    if (!isAllowed) {
+                        throw new IllegalArgumentException("Driver URL does 
not match any allowed paths: " + driverUrl);
+                    } else {
+                        return driverUrl;
+                    }
+                }
             }
-            return driverUrl;
         } catch (URISyntaxException e) {
             LOG.warn("invalid jdbc driver url: " + driverUrl);
             return driverUrl;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
index c8dfb7dfe4d..f74c93056ea 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
@@ -104,11 +104,6 @@ public class JdbcExternalCatalog extends ExternalCatalog {
             jdbcUrl = JdbcResource.handleJdbcUrl(jdbcUrl);
             properties.put(JdbcResource.JDBC_URL, jdbcUrl);
         }
-
-        if (properties.containsKey(JdbcResource.DRIVER_URL) && 
!properties.containsKey(JdbcResource.CHECK_SUM)) {
-            properties.put(JdbcResource.CHECK_SUM,
-                    
JdbcResource.computeObjectChecksum(properties.get(JdbcResource.DRIVER_URL)));
-        }
         return properties;
     }
 
@@ -231,10 +226,21 @@ public class JdbcExternalCatalog extends ExternalCatalog {
         if (isReplay) {
             return;
         }
-        Map<String, String> properties = Maps.newHashMap();
-        if (properties.containsKey(JdbcResource.DRIVER_URL) && 
!properties.containsKey(JdbcResource.CHECK_SUM)) {
-            properties.put(JdbcResource.CHECK_SUM,
-                    
JdbcResource.computeObjectChecksum(properties.get(JdbcResource.DRIVER_URL)));
+        Map<String, String> properties = catalogProperty.getProperties();
+        if (properties.containsKey(JdbcResource.DRIVER_URL)) {
+            String computedChecksum = 
JdbcResource.computeObjectChecksum(properties.get(JdbcResource.DRIVER_URL));
+            if (properties.containsKey(JdbcResource.CHECK_SUM)) {
+                String providedChecksum = 
properties.get(JdbcResource.CHECK_SUM);
+                if (!providedChecksum.equals(computedChecksum)) {
+                    throw new DdlException(
+                            "The provided checksum (" + providedChecksum
+                                    + ") does not match the computed checksum 
(" + computedChecksum
+                                    + ") for the driver_url."
+                    );
+                }
+            } else {
+                catalogProperty.addProperty(JdbcResource.CHECK_SUM, 
computedChecksum);
+            }
         }
     }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/catalog/JdbcResourceTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/catalog/JdbcResourceTest.java
index ee0d1949be2..b88597eca25 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/JdbcResourceTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/JdbcResourceTest.java
@@ -20,6 +20,7 @@ package org.apache.doris.catalog;
 import org.apache.doris.analysis.AccessTestUtil;
 import org.apache.doris.analysis.Analyzer;
 import org.apache.doris.analysis.CreateResourceStmt;
+import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.common.UserException;
@@ -201,5 +202,19 @@ public class JdbcResourceTest {
         // Ensure the result URL still contains ';'
         Assert.assertTrue(resultUrl.contains(";"));
     }
+
+    @Test
+    public void testJdbcDriverPtah() {
+        String driverPath = "postgresql-42.5.0.jar";
+        Config.jdbc_driver_secure_path = "";
+        String fullPath = JdbcResource.getFullDriverUrl(driverPath);
+        Assert.assertEquals(fullPath, "file://" + Config.jdbc_drivers_dir + 
"/" + driverPath);
+        Config.jdbc_driver_secure_path = "file:///jdbc/;http://jdbc";;
+        String driverPath2 = "file:///postgresql-42.5.0.jar";
+        Exception exception = 
Assert.assertThrows(IllegalArgumentException.class, () -> {
+            JdbcResource.getFullDriverUrl(driverPath2);
+        });
+        Assert.assertEquals("Driver URL does not match any allowed paths: 
file:///postgresql-42.5.0.jar", exception.getMessage());
+    }
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to