diff --git a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/JdbcDriverType.java b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/JdbcDriverType.java
new file mode 100644
index 00000000000..2627c586144
--- /dev/null
+++ b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/JdbcDriverType.java
@@ -0,0 +1,39 @@
+/*
+ * 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.linkis.common.utils;
+
+/**
+ * Identifies the JDBC driver family for security-policy dispatch.
+ *
+ *
Used by {@link SecurityUtils#checkJdbcConnParams(JdbcDriverType, String, Integer, String,
+ * String, String, java.util.Map)} and {@link SecurityUtils#buildSecureProperties(JdbcDriverType,
+ * String, String, java.util.Map)} so that each driver family gets its own sensitive-parameter
+ * denylist and force-set security defaults.
+ */
+public enum JdbcDriverType {
+ MYSQL,
+ POSTGRESQL,
+ GREENPLUM,
+ KINGBASE,
+ ORACLE,
+ SQLSERVER,
+ DB2,
+ CLICKHOUSE,
+ DM,
+ STARROCKS
+}
diff --git a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/SecurityUtils.java b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/SecurityUtils.java
index bddc2300b7d..e8848aad282 100644
--- a/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/SecurityUtils.java
+++ b/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/utils/SecurityUtils.java
@@ -82,6 +82,74 @@ public abstract class SecurityUtils {
private static final String BLACKLIST_REGEX =
"autodeserialize|allowloadlocalinfile|allowurlinlocalinfile|allowloadlocalinfileinpath";
+ // ----------------------- Generic JDBC security layer -----------------------
+ // The methods below extend CVE-2023-49566 coverage from MySQL-only to every
+ // JDBC driver family used by the metadata-query / datasource-manager modules.
+ // They were missing previously, which left PostgreSQL/Oracle/SQLServer/DB2/
+ // ClickHouse/KingBase/Greenplum/DM streaming user-supplied params straight
+ // into DriverManager.getConnection with no allowlist/denylist.
+
+ /** Master switch for the generic JDBC parameter check (independent of the MySQL switch). */
+ private static final CommonVars JDBC_SECURITY_CHECK_ENABLE =
+ CommonVars$.MODULE$.apply("linkis.jdbc.security.check.enable", "true");
+
+ /**
+ * Parameters blocked for every driver family. The '#', '&', '?' characters block URL-injection
+ * tricks that smuggle extra segments into the JDBC URL itself.
+ */
+ private static final CommonVars JDBC_GLOBAL_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.global.blocked.params",
+ "autoDeserialize,#,allowLoadLocalInfile,allowLocalInfile,allowUrlInLocalInfile");
+
+ /**
+ * Per-driver denylist. PG-family drivers (PostgreSQL, Greenplum, KingBase) reflectively
+ * instantiate socketFactory/sslfactory classes -> RCE on drivers below 42.2.25 / 42.3.2. DB2's
+ * clientRerouteServerListJNDIName is the original CVE-2023-49566 JNDI sink. Oracle's
+ * tns_admin/trustStore can hijack TLS / TNS configuration. SQL Server's jaasConfigurationName can
+ * trigger a JAAS lookup.
+ */
+ private static final CommonVars JDBC_POSTGRES_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.postgres.blocked.params",
+ "socketFactory,socketFactoryArg,sslfactory,sslfactoryarg,sslhostnameverifier,"
+ + "loggerLevel,loggerFile");
+
+ private static final CommonVars JDBC_DB2_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.db2.blocked.params",
+ "clientRerouteServerListJNDIName,enableSeamlessFailover,JNDIName");
+
+ private static final CommonVars JDBC_ORACLE_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.oracle.blocked.params",
+ "oracle.net.tns_admin,javax.net.ssl.trustStore,javax.net.ssl.trustStorePassword,"
+ + "oracle.net.ssl_url,javax.net.ssl.keyStore");
+
+ private static final CommonVars JDBC_SQLSERVER_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.sqlserver.blocked.params", "jaasConfigurationName,jaasApplicationName");
+
+ /** Force-set defaults applied to every driver family. Empty map means no override. */
+ private static final CommonVars JDBC_POSTGRES_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.postgres.force.params", "");
+
+ private static final CommonVars JDBC_DB2_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.db2.force.params", "");
+
+ private static final CommonVars JDBC_ORACLE_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.oracle.force.params", "");
+
+ private static final CommonVars JDBC_SQLSERVER_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.sqlserver.force.params", "trustServerCertificate=false");
+
+ private static final CommonVars JDBC_CLICKHOUSE_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.clickhouse.force.params", "");
+
+ private static final CommonVars JDBC_DM_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.dm.force.params", "");
+
/**
* check mysql connection params
*
@@ -390,6 +458,264 @@ public static Properties getMysqlSecurityParams() {
return properties;
}
+ // ----------------------- Generic JDBC API (added for CVE-2023-49566 fix-up)
+ // -----------------------
+
+ /**
+ * Driver-aware replacement for the MySQL-only {@link #checkJdbcConnParams(String, Integer,
+ * String, String, String, Map)}.
+ *
+ * Validates the same invariants (non-blank host/username, URL-encode loop, denylist match on
+ * both key and value) but selects the denylist from {@code driverType} instead of always using
+ * the MySQL one.
+ *
+ * @param driverType JDBC driver family
+ * @param host connection host
+ * @param port connection port (nullable)
+ * @param username connection username
+ * @param password connection password (not inspected; only passed through)
+ * @param database connection database name (nullable)
+ * @param extraParams user-supplied params; will be mutated in place (decoded form replaces
+ * encoded form, sensitive entries removed) so the caller can hand the same map to {@link
+ * #buildSecureProperties}
+ */
+ public static void checkJdbcConnParams(
+ JdbcDriverType driverType,
+ String host,
+ Integer port,
+ String username,
+ String password,
+ String database,
+ Map extraParams) {
+ if (!Boolean.valueOf(JDBC_SECURITY_CHECK_ENABLE.getValue())) {
+ return;
+ }
+ // 1. Basic blank check. Password is allowed to be blank for some drivers.
+ if (StringUtils.isBlank(host) || StringUtils.isBlank(username)) {
+ logger.error(
+ "Invalid jdbc connection params: driverType={}, host={}, username={}, database={}",
+ driverType,
+ host,
+ username,
+ database);
+ throw new LinkisSecurityException(35000, "Invalid jdbc connection params.");
+ }
+ // 2. Host sanity check: reject hosts that smuggle extra URL segments
+ // (e.g. "host:port/evil?socketFactory=...").
+ checkHostIsSafe(host);
+ // 3. Param denylist check (also handles URL-encoded bypass).
+ checkDriverParams(driverType, extraParams);
+ }
+
+ /**
+ * Build a JDBC {@link Properties} bag that is safe to pass to {@link
+ * java.sql.DriverManager#getConnection(String, java.util.Properties)}.
+ *
+ * The contract is identical to the MySQL secure-properties pattern: driver-specific force-set
+ * security defaults go in first, then user/password, then user-supplied params are layered on top
+ * but only if their key does not already exist (so the security defaults always win). This
+ * replaces the unsafe pattern of string-concatenating extraParams onto the JDBC URL.
+ */
+ public static Properties buildSecureProperties(
+ JdbcDriverType driverType,
+ String username,
+ String password,
+ Map extraParams) {
+ Properties props = new Properties();
+ // 1. Driver-specific force params first — these cannot be overridden by user input.
+ Map forceParams = getDriverForceParams(driverType);
+ for (Map.Entry entry : forceParams.entrySet()) {
+ props.setProperty(entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ // 2. Credentials.
+ if (username != null) {
+ props.setProperty("user", username);
+ }
+ if (password != null) {
+ props.setProperty("password", password);
+ }
+ // 3. User params, but never overwrite the force-set keys.
+ if (extraParams != null) {
+ for (Map.Entry entry : extraParams.entrySet()) {
+ if (entry.getKey() == null) {
+ continue;
+ }
+ if (!props.containsKey(entry.getKey())) {
+ props.setProperty(entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ }
+ }
+ return props;
+ }
+
+ /** Convenience: just the denylist lookup so callers can self-check before connecting. */
+ public static List getBlockedParamNames(JdbcDriverType driverType) {
+ List blocked = new ArrayList<>();
+ Collections.addAll(blocked, parseCsv(JDBC_GLOBAL_BLOCKED_PARAMS.getValue()));
+ Collections.addAll(blocked, parseCsv(getDriverBlockedConfig(driverType).getValue()));
+ return blocked;
+ }
+
+ private static void checkDriverParams(JdbcDriverType driverType, Map paramsMap) {
+ if (paramsMap == null || paramsMap.isEmpty()) {
+ return;
+ }
+ // URL-decode loop (handles double-encoded bypass) — same trick as the MySQL path.
+ String paramUrl =
+ paramsMap.entrySet().stream()
+ .map(e -> String.join(EQUAL_SIGN, e.getKey(), String.valueOf(e.getValue())))
+ .collect(Collectors.joining(AND_SYMBOL));
+ try {
+ while (paramUrl.contains("%")) {
+ String decoded = URLDecoder.decode(paramUrl, "UTF-8");
+ if (decoded.equals(paramUrl)) {
+ break;
+ }
+ paramUrl = decoded;
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new LinkisSecurityException(35000, "jdbc connection url decode error: " + e);
+ }
+ // Rebuild the params map from the decoded form so callers see the canonical shape.
+ Map decoded = parseParamUrlToMap(paramUrl);
+ paramsMap.clear();
+ paramsMap.putAll(decoded);
+
+ // Denylist check. Match on either key or value, case-insensitive, substring match so
+ // "loggerFile" still catches "loggerfile" typos and similar evasions.
+ List blocked = getBlockedParamNames(driverType);
+ Iterator> iterator = paramsMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (StringUtils.isBlank(key) || value == null || StringUtils.isBlank(value.toString())) {
+ // Drop blank entries — they are noise.
+ iterator.remove();
+ continue;
+ }
+ if (containsAnyToken(key, value.toString(), blocked)) {
+ logger.warn(
+ "Sensitive jdbc param blocked: driverType={}, key={}, value={}",
+ driverType,
+ key,
+ value);
+ throw new LinkisSecurityException(
+ 35000, "Invalid jdbc connection parameter for driver " + driverType + ": key=" + key);
+ }
+ }
+ }
+
+ /**
+ * Reject hosts that contain URL-meaningful characters. A malicious host like
+ * "evil.com:5432/db?socketFactory=x" would otherwise smuggle params past the denylist because
+ * they live in the URL rather than in extraParams.
+ */
+ private static void checkHostIsSafe(String host) {
+ if (StringUtils.isBlank(host)) {
+ return;
+ }
+ String trimmed = host.trim();
+ if (trimmed.contains("?") || trimmed.contains("#") || trimmed.contains("&")) {
+ throw new LinkisSecurityException(35000, "Host contains forbidden URL character: " + trimmed);
+ }
+ }
+
+ private static CommonVars getDriverBlockedConfig(JdbcDriverType driverType) {
+ switch (driverType) {
+ case POSTGRESQL:
+ case GREENPLUM:
+ case KINGBASE:
+ return JDBC_POSTGRES_BLOCKED_PARAMS;
+ case DB2:
+ return JDBC_DB2_BLOCKED_PARAMS;
+ case ORACLE:
+ return JDBC_ORACLE_BLOCKED_PARAMS;
+ case SQLSERVER:
+ return JDBC_SQLSERVER_BLOCKED_PARAMS;
+ case MYSQL:
+ case STARROCKS:
+ case CLICKHOUSE:
+ case DM:
+ default:
+ // MySQL keeps using its own MYSQL_SENSITIVE_PARAMS path for backwards compatibility;
+ // ClickHouse/DM fall through with just the global denylist.
+ return JDBC_GLOBAL_BLOCKED_PARAMS;
+ }
+ }
+
+ private static Map getDriverForceParams(JdbcDriverType driverType) {
+ CommonVars source;
+ switch (driverType) {
+ case POSTGRESQL:
+ case GREENPLUM:
+ case KINGBASE:
+ source = JDBC_POSTGRES_FORCE_PARAMS;
+ break;
+ case DB2:
+ source = JDBC_DB2_FORCE_PARAMS;
+ break;
+ case ORACLE:
+ source = JDBC_ORACLE_FORCE_PARAMS;
+ break;
+ case SQLSERVER:
+ source = JDBC_SQLSERVER_FORCE_PARAMS;
+ break;
+ case CLICKHOUSE:
+ source = JDBC_CLICKHOUSE_FORCE_PARAMS;
+ break;
+ case DM:
+ source = JDBC_DM_FORCE_PARAMS;
+ break;
+ case MYSQL:
+ case STARROCKS:
+ default:
+ return new LinkedHashMap<>();
+ }
+ return parseParamUrlToMap(source.getValue());
+ }
+
+ private static boolean containsAnyToken(String key, String value, List tokens) {
+ String lowerKey = key.toLowerCase();
+ String lowerValue = value.toLowerCase();
+ for (String token : tokens) {
+ if (StringUtils.isBlank(token)) {
+ continue;
+ }
+ String lower = token.toLowerCase();
+ if (lowerKey.contains(lower) || lowerValue.contains(lower)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String[] parseCsv(String csv) {
+ if (StringUtils.isBlank(csv)) {
+ return new String[0];
+ }
+ return csv.split(COMMA);
+ }
+
+ private static Map parseParamUrlToMap(String paramsUrl) {
+ Map map = new LinkedHashMap<>();
+ if (StringUtils.isBlank(paramsUrl)) {
+ return map;
+ }
+ for (String param : paramsUrl.split(AND_SYMBOL)) {
+ int idx = param.indexOf(EQUAL_SIGN);
+ if (idx < 0) {
+ continue;
+ }
+ String k = param.substring(0, idx);
+ String v = param.substring(idx + 1);
+ if (StringUtils.isNotBlank(k)) {
+ map.put(k, v);
+ }
+ }
+ return map;
+ }
+
/**
* Check if the path has a relative path
*
diff --git a/linkis-commons/linkis-common/src/test/java/org/apache/linkis/common/utils/SecurityUtilsTest.java b/linkis-commons/linkis-common/src/test/java/org/apache/linkis/common/utils/SecurityUtilsTest.java
index 95b2c3f0e21..860bc8b154b 100644
--- a/linkis-commons/linkis-common/src/test/java/org/apache/linkis/common/utils/SecurityUtilsTest.java
+++ b/linkis-commons/linkis-common/src/test/java/org/apache/linkis/common/utils/SecurityUtilsTest.java
@@ -25,6 +25,7 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.Properties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@@ -356,4 +357,180 @@ public void testMapToString() {
str = SecurityUtils.parseParamsMapToMysqlParamUrl(null);
Assertions.assertEquals("", str);
}
+
+ // ----------------------- Generic JDBC API tests (CVE-2023-49566 fix-up) -----------------------
+
+ private void assertDriverRejectsParam(JdbcDriverType driver, String key, String value) {
+ Map params = new HashMap<>();
+ params.put(key, value);
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () -> SecurityUtils.checkJdbcConnParams(driver, "localhost", 5432, "u", "p", "db", params),
+ "driver " + driver + " should reject param " + key);
+ }
+
+ @Test
+ public void testGenericCheck_PostgresDenylist() {
+ // The headline RCE sink from the advisory — must be blocked for every PG-family driver.
+ assertDriverRejectsParam(
+ JdbcDriverType.POSTGRESQL,
+ "socketFactory",
+ "org.springframework.context.support.ClassPathXmlApplicationContext");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "socketFactoryArg", "http://evil/poc.xml");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "sslfactory", "evil.Class");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "sslfactoryarg", "evil");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "loggerFile", "/tmp/evil.log");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "loggerLevel", "TRACE");
+ // Greenplum and KingBase share the PG-family denylist.
+ assertDriverRejectsParam(JdbcDriverType.GREENPLUM, "socketFactory", "evil.Class");
+ assertDriverRejectsParam(JdbcDriverType.KINGBASE, "socketFactory", "evil.Class");
+ }
+
+ @Test
+ public void testGenericCheck_Db2JndiParam() {
+ // clientRerouteServerListJNDIName is the original CVE-2023-49566 JNDI sink.
+ assertDriverRejectsParam(
+ JdbcDriverType.DB2, "clientRerouteServerListJNDIName", "ldap://evil/exp");
+ assertDriverRejectsParam(JdbcDriverType.DB2, "enableSeamlessFailover", "true");
+ assertDriverRejectsParam(JdbcDriverType.DB2, "JNDIName", "ldap://evil/exp");
+ }
+
+ @Test
+ public void testGenericCheck_OracleDenylist() {
+ assertDriverRejectsParam(JdbcDriverType.ORACLE, "oracle.net.tns_admin", "/etc/evil");
+ assertDriverRejectsParam(JdbcDriverType.ORACLE, "javax.net.ssl.trustStore", "/etc/evil");
+ assertDriverRejectsParam(JdbcDriverType.ORACLE, "javax.net.ssl.trustStorePassword", "hunter2");
+ assertDriverRejectsParam(JdbcDriverType.ORACLE, "javax.net.ssl.keyStore", "/etc/evil");
+ }
+
+ @Test
+ public void testGenericCheck_SqlserverDenylist() {
+ assertDriverRejectsParam(JdbcDriverType.SQLSERVER, "jaasConfigurationName", "evil");
+ assertDriverRejectsParam(JdbcDriverType.SQLSERVER, "jaasApplicationName", "evil");
+ }
+
+ @Test
+ public void testGenericCheck_GlobalDenylistAppliesToAllDrivers() {
+ // The global denylist (autoDeserialize, allowLoadLocalInfile, #) applies even to drivers
+ // that have no driver-specific denylist entry (ClickHouse, DM).
+ assertDriverRejectsParam(JdbcDriverType.CLICKHOUSE, "autoDeserialize", "true");
+ assertDriverRejectsParam(JdbcDriverType.CLICKHOUSE, "#", "true");
+ assertDriverRejectsParam(JdbcDriverType.DM, "autoDeserialize", "true");
+ assertDriverRejectsParam(JdbcDriverType.POSTGRESQL, "autoDeserialize", "true");
+ assertDriverRejectsParam(JdbcDriverType.ORACLE, "allowLoadLocalInfile", "true");
+ }
+
+ @Test
+ public void testGenericCheck_UrlEncodedBypass() {
+ // Attacker URL-encodes a char in a blocked param name hoping to slip past the substring
+ // match. The decoder loop should normalize it back before matching.
+ Map params = new HashMap<>();
+ params.put("%73ocketFactory", "evil.Class"); // %73 = 's'
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, "localhost", 5432, "u", "p", "db", params));
+
+ // Value-side bypass attempt should also be caught.
+ Map params2 = new HashMap<>();
+ params2.put("safeKey", "soc%6betFactory"); // %6b = 'k'
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, "localhost", 5432, "u", "p", "db", params2));
+ }
+
+ @Test
+ public void testGenericCheck_HostInjection() {
+ // A malicious host string tries to smuggle extra URL segments past the denylist.
+ Map params = new HashMap<>();
+ params.put("k1", "v1");
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL,
+ "evil.com:5432/db?socketFactory=x",
+ 5432,
+ "u",
+ "p",
+ "db",
+ params));
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, "evil.com#frag", 5432, "u", "p", "db", params));
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, "evil.com&extra=x", 5432, "u", "p", "db", params));
+ }
+
+ @Test
+ public void testGenericCheck_BlankHostOrUsername() {
+ Map params = new HashMap<>();
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, " ", 5432, "u", "p", "db", params));
+ Assertions.assertThrows(
+ LinkisSecurityException.class,
+ () ->
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL, "localhost", 5432, " ", "p", "db", params));
+ }
+
+ @Test
+ public void testGenericCheck_AllowsSafeParams() {
+ // Sanity: a benign param set for each driver family must not trip the denylist.
+ for (JdbcDriverType driver : JdbcDriverType.values()) {
+ Map params = new HashMap<>();
+ params.put("connectTimeout", "5000");
+ params.put("socketTimeout", "10000");
+ Assertions.assertDoesNotThrow(
+ () ->
+ SecurityUtils.checkJdbcConnParams(driver, "localhost", 5432, "u", "p", "db", params),
+ "driver " + driver + " should accept benign params");
+ }
+ }
+
+ @Test
+ public void testBuildSecureProperties_CredentialsPropagated() {
+ Map params = new HashMap<>();
+ params.put("connectTimeout", "5000");
+ Properties props =
+ SecurityUtils.buildSecureProperties(JdbcDriverType.POSTGRESQL, "alice", "secret", params);
+ Assertions.assertEquals("alice", props.getProperty("user"));
+ Assertions.assertEquals("secret", props.getProperty("password"));
+ Assertions.assertEquals("5000", props.getProperty("connectTimeout"));
+ }
+
+ @Test
+ public void testBuildSecureProperties_ForceParamsWinOverUserInput() {
+ // SQL Server has a force-set default of trustServerCertificate=false. Even if the user
+ // explicitly requests trustServerCertificate=true, the security default must win.
+ Map params = new HashMap<>();
+ params.put("trustServerCertificate", "true");
+ Properties props =
+ SecurityUtils.buildSecureProperties(JdbcDriverType.SQLSERVER, "u", "p", params);
+ Assertions.assertEquals("false", props.getProperty("trustServerCertificate"));
+ }
+
+ @Test
+ public void testBuildSecureProperties_GlobalForceParamsWinOverUserInput() {
+ // Drivers without a driver-specific force-set (Postgres) still have the global denylist,
+ // but the force-set behavior is verified via SQL Server's trustServerCertificate above.
+ // Here we just check that user params propagate when there is no conflict.
+ Map params = new HashMap<>();
+ params.put("applicationName", "linkis");
+ Properties props =
+ SecurityUtils.buildSecureProperties(JdbcDriverType.POSTGRESQL, "u", "p", params);
+ Assertions.assertEquals("linkis", props.getProperty("applicationName"));
+ Assertions.assertEquals("u", props.getProperty("user"));
+ }
}
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/AbstractSqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/AbstractSqlConnection.java
index 970bee1e189..efc3f00ee2e 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/AbstractSqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/AbstractSqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -29,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -192,19 +194,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: even though this class is currently unused, route through
+ // SecurityUtils so a future revival cannot reintroduce the URL-concatenation sink.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
index 50e6a0f3fcc..573c45dbdee 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
@@ -19,17 +19,17 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
-import org.apache.commons.collections.MapUtils;
-
import java.io.Closeable;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -164,19 +164,28 @@ private List getPrimaryKeys(Connection connection, String table) throws
*/
public Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
+ // CVE-2023-49566 fix-up: validate params (ClickHouse falls under the global denylist) and
+ // route through Properties instead of concatenating extraParams onto the URL.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.CLICKHOUSE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.CLICKHOUSE,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (MapUtils.isNotEmpty(connectMessage.extraParams)) {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
public String getSqlConnectUrl() {
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
index 5c368afc351..963a68b8d8b 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -29,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -211,19 +213,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: DB2's clientRerouteServerListJNDIName is the JNDI-injection
+ // sink from the original advisory; enforce the DB2 denylist and route through Properties.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.DB2,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.DB2,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
index eacdfafe38f..558a89154a8 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.commons.lang3.StringUtils;
@@ -27,7 +29,6 @@
import java.io.IOException;
import java.sql.*;
import java.util.*;
-import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -204,29 +205,30 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and route through Properties.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.DM,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties prop =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.DM,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
+ // DM-specific default kept from the historical implementation.
+ prop.put("remarksReporting", "true");
+
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- try {
- // return DriverManager.getConnection(url, connectMessage.username,
- // connectMessage.password);
- Properties prop = new Properties();
- prop.put("user", connectMessage.username);
- prop.put("password", AESUtils.isDecryptByConf(connectMessage.password));
- prop.put("remarksReporting", "true");
- return DriverManager.getConnection(url, prop);
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, prop);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
index 938c343d5bf..3fa87c4bf0e 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -29,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -196,19 +198,27 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: Greenplum is PG-derived so it inherits the PG denylist.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.GREENPLUM,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.GREENPLUM,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
index a753f41796a..131b92072e7 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import java.io.Closeable;
@@ -27,7 +29,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -210,24 +212,30 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: KingBase is PG-derived so it inherits the PG denylist
+ // (socketFactory / sslfactory ...). Route through Properties, never URL concatenation.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.KINGBASE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.KINGBASE,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
+ // URL template already contains safe hardcoded defaults; user-controlled params go via
+ // Properties only.
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- try {
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
index 142effeedbb..623b7f68b7f 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.commons.lang3.StringUtils;
@@ -27,7 +29,6 @@
import java.io.IOException;
import java.sql.*;
import java.util.*;
-import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -216,10 +217,25 @@ public void close() throws IOException {
private Connection getDBConnection(
ConnectMessage connectMessage, String database, String serviceName)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and build Properties via SecurityUtils so the
+ // Oracle denylist (oracle.net.tns_admin / javax.net.ssl.trustStore ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.ORACLE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties prop =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.ORACLE,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
+ // Oracle-specific default that must always be present.
+ prop.put("remarksReporting", "true");
+
Class.forName(SQL_DRIVER_CLASS.getValue());
String url = "";
if (StringUtils.isNotBlank(database)) {
@@ -234,14 +250,7 @@ private Connection getDBConnection(
connectMessage.port,
database);
}
-
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- Properties prop = new Properties();
- prop.put("user", connectMessage.username);
- prop.put("password", AESUtils.isDecryptByConf(connectMessage.password));
- prop.put("remarksReporting", "true");
+ LOG.info("jdbc connection url: {}", url);
return DriverManager.getConnection(url, prop);
}
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
index f72f7284d3d..958d5953698 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -29,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -192,19 +194,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and route through Properties so the
+ // PG denylist (socketFactory / sslfactory / loggerFile ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
index cb86ab169b0..039efe846dd 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
@@ -19,6 +19,8 @@
import org.apache.linkis.common.conf.CommonVars;
import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import java.io.Closeable;
@@ -27,7 +29,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -203,21 +205,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and route through Properties so the
+ // SQL Server denylist (jaasConfigurationName / jaasApplicationName ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.SQLSERVER,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.SQLSERVER,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- // String url = String.format(SQL_CONNECT_URL.getValue(), connectMessage.host,
- // database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
index 81cbe029b72..618c99339e1 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/clickhouse/SqlConnection.java
@@ -18,6 +18,8 @@
package org.apache.linkis.metadata.query.service.clickhouse;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import java.io.Closeable;
@@ -26,7 +28,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -188,18 +190,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params (ClickHouse falls under the global denylist) and
+ // route through Properties instead of concatenating extraParams onto the URL.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.CLICKHOUSE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.CLICKHOUSE,
+ connectMessage.username,
+ connectMessage.password,
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(url, connectMessage.username, connectMessage.password);
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
index 25f8cfcbcdd..ac5f7a88d3e 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/db2/SqlConnection.java
@@ -18,6 +18,9 @@
package org.apache.linkis.metadata.query.service.db2;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -28,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -200,19 +203,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: DB2's clientRerouteServerListJNDIName is the JNDI-injection
+ // sink from the original advisory; enforce the DB2 denylist and route through Properties.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.DB2,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.DB2,
+ connectMessage.username,
+ AESUtils.isDecryptByConf(connectMessage.password),
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
index e19dda991aa..9fcae42fd2a 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/dm/SqlConnection.java
@@ -18,6 +18,9 @@
package org.apache.linkis.metadata.query.service.dm;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.commons.lang3.StringUtils;
@@ -26,7 +29,7 @@
import java.io.IOException;
import java.sql.*;
import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -196,29 +199,29 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and route through Properties.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.DM,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ // DM keeps AES-decrypting the stored password before handing it to the driver.
+ String decryptedPassword = AESUtils.isDecryptByConf(connectMessage.password);
+ Properties prop =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.DM, connectMessage.username, decryptedPassword, connectMessage.extraParams);
+ // DM-specific default kept from the historical implementation.
+ prop.put("remarksReporting", "true");
+
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- try {
- // return DriverManager.getConnection(url, connectMessage.username,
- // connectMessage.password);
- Properties prop = new Properties();
- prop.put("user", connectMessage.username);
- prop.put("password", connectMessage.password);
- prop.put("remarksReporting", "true");
- return DriverManager.getConnection(url, prop);
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, prop);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
index 7c127b4a71c..c6f337fb79e 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/greenplum/SqlConnection.java
@@ -18,6 +18,9 @@
package org.apache.linkis.metadata.query.service.greenplum;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.AESUtils;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.logging.log4j.util.Strings;
@@ -28,7 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -195,19 +198,29 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: Greenplum is PG-derived so it inherits the PG denylist.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.GREENPLUM,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ // Greenplum keeps AES-decrypting the stored password before handing it to the driver.
+ String decryptedPassword = AESUtils.isDecryptByConf(connectMessage.password);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.GREENPLUM,
+ connectMessage.username,
+ decryptedPassword,
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(
- url, connectMessage.username, AESUtils.isDecryptByConf(connectMessage.password));
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
index 6eba1fe3bff..aa15a0e3c9e 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/kingbase/SqlConnection.java
@@ -18,6 +18,8 @@
package org.apache.linkis.metadata.query.service.kingbase;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import java.io.Closeable;
@@ -26,7 +28,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -177,23 +179,30 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: KingBase is PG-derived so it inherits the PG denylist
+ // (socketFactory / sslfactory ...). Route through Properties, never URL concatenation.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.KINGBASE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.KINGBASE,
+ connectMessage.username,
+ connectMessage.password,
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
+ // URL template already contains safe hardcoded defaults (zeroDateTimeBehavior etc.); those
+ // stay in the URL. User-controlled params go through Properties only.
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- try {
- return DriverManager.getConnection(url, connectMessage.username, connectMessage.password);
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
index 6a99a043e8f..c0f96f8ec73 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/oracle/SqlConnection.java
@@ -18,6 +18,8 @@
package org.apache.linkis.metadata.query.service.oracle;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import org.apache.commons.lang3.StringUtils;
@@ -213,10 +215,25 @@ public void close() throws IOException {
private Connection getDBConnection(
ConnectMessage connectMessage, String database, String serviceName)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and build Properties via SecurityUtils so the
+ // Oracle denylist (oracle.net.tns_admin / javax.net.ssl.trustStore ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.ORACLE,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties prop =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.ORACLE,
+ connectMessage.username,
+ connectMessage.password,
+ connectMessage.extraParams);
+ // Oracle-specific defaults that must always be present.
+ prop.put("remarksReporting", "true");
+
Class.forName(SQL_DRIVER_CLASS.getValue());
String url = "";
if (StringUtils.isNotBlank(database)) {
@@ -231,14 +248,7 @@ private Connection getDBConnection(
connectMessage.port,
database);
}
-
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- Properties prop = new Properties();
- prop.put("user", connectMessage.username);
- prop.put("password", connectMessage.password);
- prop.put("remarksReporting", "true");
+ LOG.info("jdbc connection url: {}", url);
return DriverManager.getConnection(url, prop);
}
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
index 02acd76a966..cfdfd31b15b 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/postgres/SqlConnection.java
@@ -18,9 +18,10 @@
package org.apache.linkis.metadata.query.service.postgres;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
-import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.util.Strings;
import java.io.Closeable;
@@ -29,7 +30,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -182,18 +183,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
+ // CVE-2023-49566 fix-up: validate params and route through Properties so the
+ // PG denylist (socketFactory / sslfactory / loggerFile ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.POSTGRESQL,
+ connectMessage.username,
+ connectMessage.password,
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (MapUtils.isNotEmpty(connectMessage.extraParams)) {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(url, connectMessage.username, connectMessage.password);
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */
diff --git a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
index 0d3597380e2..5415d32dedb 100644
--- a/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
+++ b/linkis-public-enhancements/linkis-datasource/linkis-metadata-query/service/jdbc/src/main/java/org/apache/linkis/metadata/query/service/sqlserver/SqlConnection.java
@@ -18,6 +18,8 @@
package org.apache.linkis.metadata.query.service.sqlserver;
import org.apache.linkis.common.conf.CommonVars;
+import org.apache.linkis.common.utils.JdbcDriverType;
+import org.apache.linkis.common.utils.SecurityUtils;
import org.apache.linkis.metadata.query.common.domain.MetaColumnInfo;
import java.io.Closeable;
@@ -26,7 +28,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -196,18 +198,28 @@ public void close() throws IOException {
*/
private Connection getDBConnection(ConnectMessage connectMessage, String database)
throws ClassNotFoundException, SQLException {
- String extraParamString =
- connectMessage.extraParams.entrySet().stream()
- .map(e -> String.join("=", e.getKey(), String.valueOf(e.getValue())))
- .collect(Collectors.joining("&"));
+ // CVE-2023-49566 fix-up: validate params and route through Properties so the
+ // SQL Server denylist (jaasConfigurationName / jaasApplicationName ...) is enforced.
+ SecurityUtils.checkJdbcConnParams(
+ JdbcDriverType.SQLSERVER,
+ connectMessage.host,
+ connectMessage.port,
+ connectMessage.username,
+ connectMessage.password,
+ database,
+ connectMessage.extraParams);
+ Properties props =
+ SecurityUtils.buildSecureProperties(
+ JdbcDriverType.SQLSERVER,
+ connectMessage.username,
+ connectMessage.password,
+ connectMessage.extraParams);
Class.forName(SQL_DRIVER_CLASS.getValue());
String url =
String.format(
SQL_CONNECT_URL.getValue(), connectMessage.host, connectMessage.port, database);
- if (!connectMessage.extraParams.isEmpty()) {
- url += "?" + extraParamString;
- }
- return DriverManager.getConnection(url, connectMessage.username, connectMessage.password);
+ LOG.info("jdbc connection url: {}", url);
+ return DriverManager.getConnection(url, props);
}
/** Connect message */