Files
goclaw/internal/mcp/manager_env_test.go
viettranx c81cf6cf39 feat(security): MCP validation + hooks context isolation
Phase 02 - MCP input validation:
- Add command allowlist (node, python, npx, uvx, etc.)
- Block dangerous args (--eval, -e, -c, exec(), etc.)
- SSRF protection via security.Validate() with DNS rebinding check
- Fail-closed env var allowlist for headers
- Integrate validation in create/update/import handlers

Phase 03 - Hooks async context leak:
- Use context.WithoutCancel to preserve TenantID/UserID in async hooks
- Increase audit write timeout 2s → 5s
- Increase circuit breaker store timeout 1s → 2s

Also: Add security guard tests for skills upload
2026-04-16 17:19:50 +07:00

67 lines
1.4 KiB
Go

package mcp
import (
"testing"
)
func TestResolveEnvVars(t *testing.T) {
t.Setenv("HOME", "/home/testuser")
t.Setenv("USER", "testuser")
tests := []struct {
name string
input map[string]string
want map[string]string
wantErr bool
}{
{
name: "resolves allowed env prefix",
input: map[string]string{"X-User": "env:USER", "X-Custom": "literal"},
want: map[string]string{"X-User": "testuser", "X-Custom": "literal"},
wantErr: false,
},
{
name: "resolves HOME env var",
input: map[string]string{"X-Home": "env:HOME"},
want: map[string]string{"X-Home": "/home/testuser"},
wantErr: false,
},
{
name: "nil map",
input: nil,
want: map[string]string{},
wantErr: false,
},
{
name: "rejects non-allowlisted env var",
input: map[string]string{"Authorization": "env:AWS_SECRET_KEY"},
wantErr: true,
},
{
name: "rejects sensitive env var",
input: map[string]string{"X-Token": "env:DATABASE_PASSWORD"},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := resolveEnvVars(tt.input)
if tt.wantErr {
if err == nil {
t.Error("expected error, got nil")
}
return
}
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
for k, v := range tt.want {
if got[k] != v {
t.Errorf("key %q: got %q, want %q", k, got[k], v)
}
}
})
}
}