Skip to content

Commit cd263a4

Browse files
authored
Merge pull request #185 from jumpserver/pr@dev@fix_jdbc_injection
fix: validate database identifier before JDBC URL interpolation
2 parents 1f9f503 + f12ec1e commit cd263a4

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

backend/framework/src/main/java/org/jumpserver/chen/framework/datasource/base/BaseConnectionManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.jumpserver.chen.framework.driver.DriverClassLoader;
1111
import org.jumpserver.chen.framework.driver.DriverManager;
1212
import org.jumpserver.chen.framework.i18n.MessageUtils;
13+
import org.jumpserver.chen.framework.utils.SqlIdentifierUtils;
1314

1415
import java.lang.reflect.InvocationTargetException;
1516
import java.sql.Connection;
@@ -120,6 +121,9 @@ public DruidDataSource getOrInitDataSource(String database) throws SQLException
120121
if (StringUtils.isEmpty(database)) {
121122
database = this.connectInfo.getDb();
122123
}
124+
// Reject URL metacharacters before interpolation into the JDBC URL,
125+
// preventing injection of driver connection properties.
126+
SqlIdentifierUtils.validateDatabaseName(database);
123127
if (this.dataSourceMap.containsKey(database)) {
124128
return this.dataSourceMap.get(database);
125129
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.jumpserver.chen.framework.utils;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
5+
import java.sql.SQLException;
6+
7+
/**
8+
* Validates runtime database identifiers before they are interpolated into a
9+
* JDBC URL, so that URL/property metacharacters in a database name cannot
10+
* inject driver connection properties (e.g. PostgreSQL socketFactory/loggerFile,
11+
* SQLServer ";prop=val").
12+
*/
13+
@Slf4j
14+
public final class SqlIdentifierUtils {
15+
16+
// Characters that act as delimiters in at least one supported JDBC URL form.
17+
// Rejecting them keeps a database name from escaping its ${db} placeholder.
18+
private static final String FORBIDDEN_CHARS = "?&/:@#\\;= \t\r\n";
19+
20+
private SqlIdentifierUtils() {
21+
}
22+
23+
/**
24+
* Reject database names containing URL/property metacharacters or control
25+
* characters. Blank values are allowed; callers fall back to the configured db.
26+
*/
27+
public static void validateDatabaseName(String name) throws SQLException {
28+
if (name == null || name.isEmpty()) {
29+
return;
30+
}
31+
for (int i = 0; i < name.length(); i++) {
32+
char c = name.charAt(i);
33+
if (c < 0x20 || FORBIDDEN_CHARS.indexOf(c) >= 0) {
34+
// Do not echo the value: it may contain log-forging characters.
35+
log.warn("Rejected database name containing URL metacharacter");
36+
throw new SQLException("Invalid database identifier");
37+
}
38+
}
39+
}
40+
}

backend/modules/src/main/java/org.jumpserver.chen.modules/postgresql/PostgresqlSQLHintsHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.jumpserver.chen.framework.datasource.entity.resource.Field;
77
import org.jumpserver.chen.framework.datasource.entity.resource.Table;
88
import org.jumpserver.chen.framework.datasource.sql.SQL;
9+
import org.jumpserver.chen.framework.utils.SqlIdentifierUtils;
910
import org.jumpserver.chen.framework.utils.TreeUtils;
1011

1112
import java.sql.SQLException;
@@ -46,6 +47,9 @@ public Map<String, List<String>> getHints(String nodeKey, String context) throws
4647

4748
var db = TreeUtils.getValue(nodeKey, "database");
4849
if (StringUtils.isNotEmpty(db)) {
50+
// nodeKey is client-controlled; reject URL metacharacters before it
51+
// reaches the JDBC URL via setDatabaseContext.
52+
SqlIdentifierUtils.validateDatabaseName(db);
4953
this.connectionManager.setDatabaseContext(db);
5054
}
5155

0 commit comments

Comments
 (0)