You've already forked agentic-coding-workflow
73 lines
2.6 KiB
Go
73 lines
2.6 KiB
Go
package acp
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
// TestAllowlistHit 覆盖白名单匹配的边界:空 toolName 一律不放行(含 "*"),
|
|
// 白名单中的空串条目不误匹配。
|
|
func TestAllowlistHit(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
allowlist []string
|
|
toolName string
|
|
want bool
|
|
}{
|
|
{"精确命中", []string{"safe.tool"}, "safe.tool", true},
|
|
{"未命中", []string{"safe.tool"}, "other.tool", false},
|
|
{"通配符放行可识别工具", []string{"*"}, "any.tool", true},
|
|
{"通配符不放行空名", []string{"*"}, "", false},
|
|
{"空名不匹配空串条目", []string{""}, "", false},
|
|
{"空白名单", nil, "any.tool", false},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
if got := allowlistHit(c.allowlist, c.toolName); got != c.want {
|
|
t.Fatalf("allowlistHit(%v, %q) = %v, want %v", c.allowlist, c.toolName, got, c.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestExtractToolName_IgnoresAgentAssertedKindTitle 锁定安全约束:extractToolName
|
|
// 只信任真实工具名(name / toolName),绝不回退到 agent 自填的 kind / title。否则
|
|
// agent 可把 execute/shell 调用伪装成 kind='read' 或冒用白名单 title 绕过人工审批。
|
|
func TestExtractToolName_IgnoresAgentAssertedKindTitle(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
toolCall string
|
|
want string
|
|
}{
|
|
{"真实 name", `{"name":"shell.exec"}`, "shell.exec"},
|
|
{"真实 toolName", `{"toolName":"shell.exec"}`, "shell.exec"},
|
|
{"仅 kind 不取", `{"kind":"read"}`, ""},
|
|
{"仅 title 不取", `{"title":"Read file"}`, ""},
|
|
{"kind+title 都不取", `{"kind":"execute","title":"safe.tool"}`, ""},
|
|
{"name 优先于 kind/title", `{"name":"real.tool","kind":"read","title":"x"}`, "real.tool"},
|
|
{"空 toolCall", ``, ""},
|
|
{"无可识别字段", `{"unknownField":1}`, ""},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
got := extractToolName(json.RawMessage(c.toolCall))
|
|
if got != c.want {
|
|
t.Fatalf("extractToolName(%q) = %q, want %q", c.toolCall, got, c.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestAllowlist_DoesNotHonorAgentKind 端到端验证 bug #3:即使 allowlist 含 'read'
|
|
// 这类 kind 值,agent 把 execute 调用标成 kind='read' 也不会自动放行(extractToolName
|
|
// 返回空 → allowlistHit 为 false)。
|
|
func TestAllowlist_DoesNotHonorAgentKind(t *testing.T) {
|
|
toolName := extractToolName(json.RawMessage(`{"kind":"read","title":"safe"}`))
|
|
if toolName != "" {
|
|
t.Fatalf("kind/title 不应被当作工具名, got %q", toolName)
|
|
}
|
|
if allowlistHit([]string{"read", "safe", "*"}, toolName) {
|
|
t.Fatal("kind/title 伪装的调用不应命中白名单(含通配符)")
|
|
}
|
|
}
|