Files
goclaw/internal/tools/scrub_test.go
T

159 lines
4.3 KiB
Go

package tools
import "testing"
func TestScrubCredentials_OpenAI(t *testing.T) {
input := "Found key: sk-abcdefghijklmnopqrstuvwxyz1234567890 in env"
got := ScrubCredentials(input)
if got != "Found key: [REDACTED] in env" {
t.Errorf("OpenAI key not scrubbed: %s", got)
}
}
func TestScrubCredentials_Anthropic(t *testing.T) {
input := "key=sk-ant-abc123-def456-ghi789-jkl012"
got := ScrubCredentials(input)
if got != "key=[REDACTED]" {
t.Errorf("Anthropic key not scrubbed: %s", got)
}
}
func TestScrubCredentials_GitHub(t *testing.T) {
tests := []struct {
name string
input string
}{
{"ghp", "token ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij done"},
{"gho", "token gho_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij done"},
{"ghu", "token ghu_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij done"},
{"ghs", "token ghs_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij done"},
{"ghr", "token ghr_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij done"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ScrubCredentials(tt.input)
want := "token [REDACTED] done"
if got != want {
t.Errorf("GitHub %s not scrubbed: got %q, want %q", tt.name, got, want)
}
})
}
}
func TestScrubCredentials_AWS(t *testing.T) {
input := "aws_key: AKIAIOSFODNN7EXAMPLE"
got := ScrubCredentials(input)
if got == input {
t.Errorf("AWS key not scrubbed: %s", got)
}
}
func TestScrubCredentials_GenericKeyValue(t *testing.T) {
tests := []struct {
name string
input string
}{
{"api_key", "api_key=supersecretvalue123"},
{"token", "token: mysecrettoken12345"},
{"password", "password=MyStr0ngP@ssword!"},
{"bearer", "bearer: eyJhbGciOiJIUzI1NiJ9.abc"},
{"authorization", "authorization=eyJhbGciOiJIUzI1NiJ9abcdef"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ScrubCredentials(tt.input)
if got == tt.input {
t.Errorf("generic pattern %q not scrubbed: %s", tt.name, got)
}
})
}
}
func TestScrubCredentials_NoFalsePositive(t *testing.T) {
inputs := []string{
"hello world",
"sk-short", // too short for OpenAI pattern
"ghp_tooshort", // too short for GitHub pattern
"normal text with no secrets",
"AKIA1234", // too short for AWS (needs 16 chars after AKIA)
}
for _, input := range inputs {
got := ScrubCredentials(input)
if got != input {
t.Errorf("false positive on %q: got %q", input, got)
}
}
}
func TestScrubCredentials_MultiplePatterns(t *testing.T) {
input := "openai=sk-abcdefghijklmnopqrstuvwxyz, github=ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij"
got := ScrubCredentials(input)
if got == input {
t.Errorf("multiple patterns not scrubbed: %s", got)
}
}
func TestScrubCredentials_EmptyString(t *testing.T) {
got := ScrubCredentials("")
if got != "" {
t.Errorf("empty string changed: %q", got)
}
}
func TestScrubCredentials_DynamicServerIPs(t *testing.T) {
ResetDynamicScrubValues()
defer ResetDynamicScrubValues()
AddDynamicScrubValues("18.141.232.136", "34.160.111.145")
tests := []struct {
name string
input string
want string
}{
{"public IP", "Your IP: 18.141.232.136", "Your IP: [SERVER_IP]"},
{"forwarded chain", "X-Forwarded-For: 18.141.232.136, 34.160.111.145", "X-Forwarded-For: [SERVER_IP], [SERVER_IP]"},
{"unrelated IP", "Hello 1.2.3.4", "Hello 1.2.3.4"},
{"IP in URL", "http://18.141.232.136:8080/api", "http://[SERVER_IP]:8080/api"},
{"multiple occurrences", "src=18.141.232.136 dst=18.141.232.136", "src=[SERVER_IP] dst=[SERVER_IP]"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ScrubCredentials(tt.input)
if got != tt.want {
t.Errorf("got %q, want %q", got, tt.want)
}
})
}
}
func TestAddDynamicScrubValues_Dedup(t *testing.T) {
ResetDynamicScrubValues()
defer ResetDynamicScrubValues()
AddDynamicScrubValues("10.0.0.1", "10.0.0.1", "10.0.0.2")
if count := DynamicScrubCount(); count != 2 {
t.Errorf("expected 2 unique values, got %d", count)
}
}
func TestAddDynamicScrubValues_IgnoresEmpty(t *testing.T) {
ResetDynamicScrubValues()
defer ResetDynamicScrubValues()
AddDynamicScrubValues("", "", "10.0.0.1")
if count := DynamicScrubCount(); count != 1 {
t.Errorf("expected 1 value, got %d", count)
}
}
func TestDetectLocalIPs_NoLoopback(t *testing.T) {
ips := detectLocalIPs()
for _, ipStr := range ips {
if ipStr == "127.0.0.1" || ipStr == "::1" {
t.Errorf("loopback IP should be excluded: %s", ipStr)
}
}
}