🐛 fix(driver-agent): 阻止运行不匹配的驱动代理

- 连接前复用安装阶段的严格 revision 与 metadata 校验
- 对旧版或无法验证的 agent 返回明确重装错误而非继续运行
- 覆盖 stale、metadata 失败、当前版本和自定义驱动边界
- 隔离 SQL 审计测试对本机已安装 agent 的依赖
This commit is contained in:
Syngnat
2026-07-17 17:06:44 +08:00
parent 0ca8b1960c
commit 54f18cdd2f
3 changed files with 39 additions and 26 deletions

View File

@@ -1135,20 +1135,11 @@ func verifyRuntimeOptionalDriverAgentRevision(config connection.ConnectionConfig
return nil
}
displayName := resolveDriverDisplayName(driverDefinition{Type: driverType})
agentRevision, current, err := optionalDriverAgentRevisionCurrent(driverType, executablePath)
agentRevision, err := verifyInstalledOptionalDriverAgentRevision(driverType, executablePath, selectedVersion)
if err != nil {
logger.Warnf("%s driver-agent revision 元数据不可用,继续使用已安装代理:version=%s path=%s err=%v;建议在驱动管理中重装",
displayName, selectedVersion, executablePath, err)
return nil
}
if !current {
actualLabel := strings.TrimSpace(agentRevision)
if actualLabel == "" {
actualLabel = "空"
}
logger.Warnf("%s driver-agent revision 不匹配,继续使用已安装代理:已安装=%s 当前需要=%s version=%s path=%s建议在驱动管理中重装",
displayName, actualLabel, expectedRevision, selectedVersion, executablePath)
return nil
logger.Warnf("%s driver-agent revision 校验失败,已阻止使用不匹配代理:当前需要=%s version=%s path=%s err=%v",
displayName, expectedRevision, selectedVersion, executablePath, err)
return err
}
logger.Infof("%s driver-agent revision 校验通过:已安装=%s 当前需要=%s version=%s path=%s",
displayName, strings.TrimSpace(agentRevision), expectedRevision, selectedVersion, executablePath)

View File

@@ -134,7 +134,12 @@ func TestDirectDBQueryCannotBypassWriteAuditWhenBatchStartsWithRead(t *testing.T
func TestDirectDBQueryCannotBypassAuditWithNestedWriteSyntax(t *testing.T) {
originalNewDatabaseFunc := newDatabaseFunc
t.Cleanup(func() { newDatabaseFunc = originalNewDatabaseFunc })
originalVerifyDriverAgentRevisionFunc := verifyDriverAgentRevisionFunc
t.Cleanup(func() {
newDatabaseFunc = originalNewDatabaseFunc
verifyDriverAgentRevisionFunc = originalVerifyDriverAgentRevisionFunc
})
verifyDriverAgentRevisionFunc = func(connection.ConnectionConfig) error { return nil }
explainWrite := "EXPLAIN ANALYZE UPDATE users SET enabled = false WHERE id = 7"
pragmaWrite := "PRAGMA user_version = 7"
mongoWrite := `{"aggregate":"users","pipeline":[{"$merge":{"into":"users_archive"}}],"cursor":{}}`

View File

@@ -124,7 +124,7 @@ func TestVerifyInstalledOptionalDriverAgentRevisionRejectsProbeFailure(t *testin
}
}
func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsStaleOceanBaseMySQLAgent(t *testing.T) {
func TestVerifyRuntimeOptionalDriverAgentRevisionRejectsStaleOceanBaseMySQLAgent(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
optionalDriverAgentMetadataProbe = originalProbe
@@ -137,12 +137,12 @@ func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsStaleOceanBaseMySQLAgent(
}
err := verifyRuntimeOptionalDriverAgentRevision(connection.ConnectionConfig{Type: "oceanbase"})
if err != nil {
t.Fatalf("runtime revision mismatch should warn and continue, got %v", err)
if err == nil {
t.Fatal("runtime revision mismatch must reject the stale agent")
}
}
func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsStaleOceanBaseOracleAgent(t *testing.T) {
func TestVerifyRuntimeOptionalDriverAgentRevisionRejectsStaleOceanBaseOracleAgent(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
optionalDriverAgentMetadataProbe = originalProbe
@@ -158,12 +158,12 @@ func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsStaleOceanBaseOracleAgent
Type: "oceanbase",
ConnectionParams: "protocol=oracle",
})
if err != nil {
t.Fatalf("runtime revision mismatch should stay in driver manager only, got %v", err)
if err == nil {
t.Fatal("runtime revision mismatch must reject the stale agent")
}
}
func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsUnknownOceanBaseOracleAgent(t *testing.T) {
func TestVerifyRuntimeOptionalDriverAgentRevisionRejectsUnknownOceanBaseOracleAgent(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
optionalDriverAgentMetadataProbe = originalProbe
@@ -176,12 +176,12 @@ func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsUnknownOceanBaseOracleAge
Type: "oceanbase",
OceanBaseProtocol: "oracle",
})
if err != nil {
t.Fatalf("runtime metadata probe failure should stay in driver manager only, got %v", err)
if err == nil {
t.Fatal("runtime metadata probe failure must reject an unverified agent")
}
}
func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsMetadataProbeFailure(t *testing.T) {
func TestVerifyRuntimeOptionalDriverAgentRevisionRejectsMetadataProbeFailure(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
optionalDriverAgentMetadataProbe = originalProbe
@@ -191,8 +191,25 @@ func TestVerifyRuntimeOptionalDriverAgentRevisionAllowsMetadataProbeFailure(t *t
}
err := verifyRuntimeOptionalDriverAgentRevision(connection.ConnectionConfig{Type: "sqlserver"})
if err != nil {
t.Fatalf("runtime metadata probe failure should warn and continue, got %v", err)
if err == nil {
t.Fatal("runtime metadata probe failure must reject an unverified agent")
}
}
func TestVerifyRuntimeOptionalDriverAgentRevisionAcceptsCurrentAgent(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {
optionalDriverAgentMetadataProbe = originalProbe
})
optionalDriverAgentMetadataProbe = func(driverType string, executablePath string) (db.OptionalDriverAgentMetadata, error) {
return db.OptionalDriverAgentMetadata{
DriverType: driverType,
AgentRevision: db.OptionalDriverAgentRevision(driverType),
}, nil
}
if err := verifyRuntimeOptionalDriverAgentRevision(connection.ConnectionConfig{Type: "clickhouse"}); err != nil {
t.Fatalf("current runtime agent should be accepted: %v", err)
}
}