This is an automated email from the ASF dual-hosted git repository.
casionone pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/linkis.git
The following commit(s) were added to refs/heads/master by this push:
new 602467b8ad #AI COMMIT# [SECURITY][DS] Complete CVE-2023-49566 fix for
non-MySQL JDBC drivers (#5449)
602467b8ad is described below
commit 602467b8ad2442520f25ef2a0db9acb113b938b1
Author: aiceflower <[email protected]>
AuthorDate: Fri Jun 26 16:02:29 2026 +0800
#AI COMMIT# [SECURITY][DS] Complete CVE-2023-49566 fix for non-MySQL JDBC
drivers (#5449)
The CVE-2023-49566 fix shipped earlier only protected the MySQL/StarRocks
SqlConnection implementations. The eight other JDBC driver families used by
the metadata-query / datasource-manager modules (PostgreSQL, Oracle, SQL
Server, ClickHouse, KingBase, Greenplum, DM, DB2) still streamed user-
supplied extraParams straight onto the JDBC URL with no allowlist/denylist,
so any authenticated user could inject driver-specific dangerous properties:
* PG/Greenplum/KingBase: socketFactory + socketFactoryArg -> RCE on
drivers below 42.2.25 / 42.3.2
* DB2: clientRerouteServerListJNDIName -> JNDI injection (the original
CVE-2023-49566 sink)
* Oracle: oracle.net.tns_admin / javax.net.ssl.trustStore -> TLS/TNS
hijack
* SQL Server: jaasConfigurationName -> JAAS lookup
Fix extends the MySQL-only SecurityUtils path to every driver family:
* Add JdbcDriverType enum + per-driver denylist/force-params config in
SecurityUtils (checkJdbcConnParams(JdbcDriverType, ...) and
buildSecureProperties).
* All 16 SqlConnection implementations (8 drivers x 2 modules) now call
SecurityUtils.checkJdbcConnParams and route through Properties-based
DriverManager.getConnection, never URL concatenation.
* Add 10 unit tests covering each driver denylist, URL-encoded bypass,
host injection, and force-params-wins semantics.
Files:
linkis-commons/linkis-common/.../utils/JdbcDriverType.java (new)
linkis-commons/linkis-common/.../utils/SecurityUtils.java
linkis-commons/linkis-common/.../utils/SecurityUtilsTest.java
linkis-public-enhancements/linkis-datasource/linkis-datasource-manager/
service/jdbc/.../AbstractSqlConnection.java
linkis-public-enhancements/linkis-datasource/linkis-{metadata-query,
datasource-manager}/service/jdbc/.../{postgres,oracle,sqlserver,
clickhouse,kingbase,greenplum,dm,db2}/SqlConnection.java
Co-authored-by: Claude Opus 4.7 <[email protected]>
---
.../apache/linkis/common/utils/JdbcDriverType.java | 39 +++
.../apache/linkis/common/utils/SecurityUtils.java | 326 +++++++++++++++++++++
.../linkis/common/utils/SecurityUtilsTest.java | 177 +++++++++++
.../query/service/AbstractSqlConnection.java | 31 +-
.../query/service/clickhouse/SqlConnection.java | 33 ++-
.../metadata/query/service/db2/SqlConnection.java | 31 +-
.../metadata/query/service/dm/SqlConnection.java | 42 +--
.../query/service/greenplum/SqlConnection.java | 30 +-
.../query/service/kingbase/SqlConnection.java | 38 ++-
.../query/service/oracle/SqlConnection.java | 35 ++-
.../query/service/postgres/SqlConnection.java | 31 +-
.../query/service/sqlserver/SqlConnection.java | 33 ++-
.../query/service/clickhouse/SqlConnection.java | 30 +-
.../metadata/query/service/db2/SqlConnection.java | 32 +-
.../metadata/query/service/dm/SqlConnection.java | 43 +--
.../query/service/greenplum/SqlConnection.java | 33 ++-
.../query/service/kingbase/SqlConnection.java | 37 ++-
.../query/service/oracle/SqlConnection.java | 34 ++-
.../query/service/postgres/SqlConnection.java | 31 +-
.../query/service/sqlserver/SqlConnection.java | 30 +-
20 files changed, 910 insertions(+), 206 deletions(-)
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 0000000000..2627c58614
--- /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.
+ *
+ * <p>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 bddc2300b7..e8848aad28 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<String> 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<String> 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<String> JDBC_POSTGRES_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.postgres.blocked.params",
+
"socketFactory,socketFactoryArg,sslfactory,sslfactoryarg,sslhostnameverifier,"
+ + "loggerLevel,loggerFile");
+
+ private static final CommonVars<String> JDBC_DB2_BLOCKED_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.db2.blocked.params",
+ "clientRerouteServerListJNDIName,enableSeamlessFailover,JNDIName");
+
+ private static final CommonVars<String> 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<String> 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<String> JDBC_POSTGRES_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.postgres.force.params", "");
+
+ private static final CommonVars<String> JDBC_DB2_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.db2.force.params", "");
+
+ private static final CommonVars<String> JDBC_ORACLE_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.oracle.force.params", "");
+
+ private static final CommonVars<String> JDBC_SQLSERVER_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply(
+ "linkis.jdbc.sqlserver.force.params",
"trustServerCertificate=false");
+
+ private static final CommonVars<String> JDBC_CLICKHOUSE_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.clickhouse.force.params", "");
+
+ private static final CommonVars<String> JDBC_DM_FORCE_PARAMS =
+ CommonVars$.MODULE$.apply("linkis.jdbc.dm.force.params", "");
+
/**
* check mysql connection params
*
@@ -390,6 +458,264 @@ public abstract class SecurityUtils {
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)}.
+ *
+ * <p>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<String, Object> 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)}.
+ *
+ * <p>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<String, Object> extraParams) {
+ Properties props = new Properties();
+ // 1. Driver-specific force params first — these cannot be overridden by
user input.
+ Map<String, Object> forceParams = getDriverForceParams(driverType);
+ for (Map.Entry<String, Object> 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<String, Object> 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<String> getBlockedParamNames(JdbcDriverType driverType) {
+ List<String> 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<String,
Object> 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<String, Object> 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<String> blocked = getBlockedParamNames(driverType);
+ Iterator<Map.Entry<String, Object>> iterator =
paramsMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String, Object> 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<String> 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<String, Object> getDriverForceParams(JdbcDriverType
driverType) {
+ CommonVars<String> 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<String> 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<String, Object> parseParamUrlToMap(String paramsUrl) {
+ Map<String, Object> 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 95b2c3f0e2..860bc8b154 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 org.apache.commons.lang3.StringUtils;
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 class SecurityUtilsTest {
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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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 970bee1e18..efc3f00ee2 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 @@ package org.apache.linkis.metadata.query.service;
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.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;
@@ -192,19 +194,28 @@ public class AbstractSqlConnection implements Closeable {
*/
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 50e6a0f3fc..573c45dbde 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 @@ package org.apache.linkis.metadata.query.service.clickhouse;
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 @@ public class SqlConnection implements Closeable {
*/
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 5c368afc35..963a68b8d8 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 @@ 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;
@@ -29,7 +31,7 @@ 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;
@@ -211,19 +213,28 @@ public class SqlConnection implements Closeable {
*/
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 eacdfafe38..558a89154a 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 @@ 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;
@@ -27,7 +29,6 @@ import java.io.Closeable;
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 class SqlConnection implements Closeable {
*/
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 938c343d5b..3fa87c4bf0 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 @@ 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;
@@ -29,7 +31,7 @@ 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;
@@ -196,19 +198,27 @@ public class SqlConnection implements Closeable {
*/
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 a753f41796..131b92072e 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 @@ package org.apache.linkis.metadata.query.service.kingbase;
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.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;
@@ -210,24 +212,30 @@ public class SqlConnection implements Closeable {
*/
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 142effeedb..623b7f68b7 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 @@ package org.apache.linkis.metadata.query.service.oracle;
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.Closeable;
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 class SqlConnection implements Closeable {
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 @@ public class SqlConnection implements Closeable {
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 f72f7284d3..958d595369 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 @@ package org.apache.linkis.metadata.query.service.postgres;
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.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;
@@ -192,19 +194,28 @@ public class SqlConnection implements Closeable {
*/
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 cb86ab169b..039efe846d 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 @@ package org.apache.linkis.metadata.query.service.sqlserver;
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.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;
@@ -203,21 +205,28 @@ public class SqlConnection implements Closeable {
*/
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 81cbe029b7..618c99339e 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.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;
@@ -188,18 +190,28 @@ public class SqlConnection implements Closeable {
*/
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 25f8cfcbcd..ac5f7a88d3 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.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;
@@ -200,19 +203,28 @@ public class SqlConnection implements Closeable {
*/
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 e19dda991a..9fcae42fd2 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.Closeable;
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 class SqlConnection implements Closeable {
*/
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 7c127b4a71..c6f337fb79 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.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;
@@ -195,19 +198,29 @@ public class SqlConnection implements Closeable {
*/
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 6eba1fe3bf..aa15a0e3c9 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.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;
@@ -177,23 +179,30 @@ public class SqlConnection implements Closeable {
*/
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 6a99a043e8..c0f96f8ec7 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 class SqlConnection implements Closeable {
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 @@ public class SqlConnection implements Closeable {
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 02acd76a96..cfdfd31b15 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.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;
@@ -182,18 +183,28 @@ public class SqlConnection implements Closeable {
*/
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 0d3597380e..5415d32ded 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.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;
@@ -196,18 +198,28 @@ public class SqlConnection implements Closeable {
*/
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 */
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]