Files
ARTEX/server/intercept_argv_test.go
T
BaaRai 62e65f1235 Intercept: always allow a pending Bash prefix (argv allow rule, code-owned denylist)
POST /api/intercept/pending/{id}/always-allow derives an argv allow rule from the stored pending row (never from the body), at priority -1000, reusing an identical enabled rule, and leaves the request pending. A code-owned denylist of interpreters, launchers, package managers, orchestration and destructive programs refuses such rules at creation, in the manual rule form, and neutralises argv allow rules at matching; argv deny and ask rules still match.
2026-11-13 11:24:25 +01:00

55 lines
2.3 KiB
Go

package server
import (
"testing"
"github.com/Autumn-27/artex/intercept"
)
func TestValidateArgvRuleReq(t *testing.T) {
base := interceptRuleReq{Name: "r", MatchTarget: "tool_input", MatchType: "argv", Pattern: `["git","push"]`, Action: "allow"}
if err := validateInterceptRuleReq(base); err != nil {
t.Fatalf("valid argv rule refused: %v", err)
}
for name, mut := range map[string]func(*interceptRuleReq){
"tool_name target": func(r *interceptRuleReq) { r.MatchTarget = "tool_name" },
"empty pattern": func(r *interceptRuleReq) { r.Pattern = "" },
"empty token": func(r *interceptRuleReq) { r.Pattern = `["git",""]` },
"flag token": func(r *interceptRuleReq) { r.Pattern = `["git","-C"]` },
"metacharacter": func(r *interceptRuleReq) { r.Pattern = `["nmap;id"]` },
"nine tokens": func(r *interceptRuleReq) { r.Pattern = `["a","b","c","d","e","f","g","h","i"]` },
"not an array": func(r *interceptRuleReq) { r.Pattern = `git push` },
} {
req := base
mut(&req)
if err := validateInterceptRuleReq(req); err == nil {
t.Errorf("%s: accepted", name)
}
}
}
// The manual rule form refuses an argv allow rule for a denylisted program,
// with the message of the "always allow" endpoint; deny and ask stay creatable.
func TestValidateArgvAllowDenylist(t *testing.T) {
for _, pattern := range []string{`["python"]`, `["python3.11"]`, `["/usr/bin/env"]`, `["find"]`, `["docker","run"]`} {
req := interceptRuleReq{Name: "r", MatchTarget: "tool_input", MatchType: "argv", Pattern: pattern, Action: "allow"}
tokens, _ := intercept.ParseArgvPattern(pattern)
want := intercept.CheckArgvAllow(tokens)
if err := validateInterceptRuleReq(req); err == nil || want == nil || err.Error() != want.Error() {
t.Errorf("allow %s: %v, want %v", pattern, err, want)
}
for _, action := range []string{"deny", "ask"} {
req.Action = action
if err := validateInterceptRuleReq(req); err != nil {
t.Errorf("%s %s refused: %v", action, pattern, err)
}
}
}
for _, pattern := range []string{`["nmap"]`, `["git","push"]`} {
req := interceptRuleReq{Name: "r", MatchTarget: "tool_input", MatchType: "argv", Pattern: pattern, Action: "allow"}
if err := validateInterceptRuleReq(req); err != nil {
t.Errorf("allow %s refused: %v", pattern, err)
}
}
}