🐛 fix(connection): 收敛数据库连接参数白名单

- MySQL 兼容 JDBC 参数映射并丢弃 allowPublicKeyRetrieval 等无效参数
- 为 PostgreSQL 系、SQL Server、Oracle、达梦、TDengine 接入驱动参数白名单
- 补充连接参数归一化、别名映射和未知参数过滤回归测试
This commit is contained in:
Syngnat
2026-05-13 17:51:02 +08:00
parent e6a1333f83
commit b2b1e6b944
15 changed files with 874 additions and 33 deletions

View File

@@ -99,6 +99,73 @@ func normalizeMySQLServerTimezoneParam(raw string) (string, bool) {
return "", false
}
var mysqlSupportedDriverParamNames = map[string]string{
"allowallfiles": "allowAllFiles",
"allowcleartextpasswords": "allowCleartextPasswords",
"allowfallbacktoplaintext": "allowFallbackToPlaintext",
"allownativepasswords": "allowNativePasswords",
"allowoldpasswords": "allowOldPasswords",
"checkconnliveness": "checkConnLiveness",
"clientfoundrows": "clientFoundRows",
"charset": "charset",
"collation": "collation",
"columnswithalias": "columnsWithAlias",
"compress": "compress",
"connectionattributes": "connectionAttributes",
"interpolateparams": "interpolateParams",
"loc": "loc",
"maxallowedpacket": "maxAllowedPacket",
"multistatements": "multiStatements",
"parsetime": "parseTime",
"readtimeout": "readTimeout",
"rejectreadonly": "rejectReadOnly",
"serverpubkey": "serverPubKey",
"timetruncate": "timeTruncate",
"timeout": "timeout",
"tls": "tls",
"writetimeout": "writeTimeout",
}
var mysqlBoolDriverParamNames = map[string]struct{}{
"allowAllFiles": {},
"allowCleartextPasswords": {},
"allowFallbackToPlaintext": {},
"allowNativePasswords": {},
"allowOldPasswords": {},
"checkConnLiveness": {},
"clientFoundRows": {},
"columnsWithAlias": {},
"compress": {},
"interpolateParams": {},
"multiStatements": {},
"parseTime": {},
"rejectReadOnly": {},
}
func canonicalMySQLDriverParamName(name string) (string, bool) {
canonical, ok := mysqlSupportedDriverParamNames[strings.ToLower(strings.TrimSpace(name))]
return canonical, ok
}
func setMySQLDriverParam(params url.Values, name string, value string) {
switch name {
case "charset":
if charset := normalizeMySQLCharsetParam(value); charset != "" {
params.Set("charset", charset)
}
case "timeout", "readTimeout", "writeTimeout", "timeTruncate":
params.Set(name, normalizeMySQLDurationParam(value, time.Second))
default:
if _, ok := mysqlBoolDriverParamNames[name]; ok {
if enabled, ok := parseMySQLBoolParam(value); ok {
params.Set(name, strconv.FormatBool(enabled))
return
}
}
params.Set(name, value)
}
}
func mergeMySQLConnectionParam(params url.Values, key string, value string) {
name := strings.TrimSpace(key)
if name == "" {
@@ -108,12 +175,7 @@ func mergeMySQLConnectionParam(params url.Values, key string, value string) {
switch lowerName {
case "topology":
return
case "useunicode", "autoreconnect", "useoldaliasmetadatabehavior":
return
case "charset":
if charset := normalizeMySQLCharsetParam(value); charset != "" {
params.Set("charset", charset)
}
case "useunicode", "autoreconnect", "useoldaliasmetadatabehavior", "allowpublickeyretrieval":
return
case "characterencoding":
if charset := normalizeMySQLCharsetParam(value); charset != "" {
@@ -144,17 +206,41 @@ func mergeMySQLConnectionParam(params url.Values, key string, value string) {
params.Set("tls", "skip-verify")
}
return
case "sslmode":
switch normalizeSSLModeValue(value) {
case sslModeDisable:
params.Set("tls", "false")
case sslModeRequired:
params.Set("tls", "true")
case sslModeSkipVerify:
params.Set("tls", "skip-verify")
default:
params.Set("tls", "preferred")
}
return
case "connecttimeout":
params.Set("timeout", normalizeMySQLDurationParam(value, time.Millisecond))
return
case "sockettimeout":
params.Set("readTimeout", normalizeMySQLDurationParam(value, time.Millisecond))
return
case "timeout", "readtimeout", "writetimeout":
params.Set(name, normalizeMySQLDurationParam(value, time.Second))
case "allowmultiqueries":
if enabled, ok := parseMySQLBoolParam(value); ok {
params.Set("multiStatements", strconv.FormatBool(enabled))
}
return
case "usecompression":
if enabled, ok := parseMySQLBoolParam(value); ok {
params.Set("compress", strconv.FormatBool(enabled))
}
return
case "connectioncollation":
params.Set("collation", value)
return
default:
params.Set(name, value)
if canonical, ok := canonicalMySQLDriverParamName(name); ok {
setMySQLDriverParam(params, canonical, value)
}
}
}