返回 DeepSeek-Reasonix
sanitize_test.go
根目录 / internal / capdiag / sanitize_test.go
1 package capdiag
2
3 import (
4 "strings"
5 "testing"
6 )
7
8 func TestSanitizeErrTextRedactsSecretsAndPaths(t *testing.T) {
9 home := t.TempDir()
10 ws := t.TempDir()
11 in := "stdio plugin \"x\": command \"npx\" not found on PATH; PATH=\"" + home + "/bin:/usr/bin\" Bearer sk-secret-token " +
12 ws + "/secret.env stderr: Authorization=Bearer abc.def"
13 out := sanitizeErrTextWithPaths(in, ws, home, "")
14 if strings.Contains(out, home) {
15 t.Fatalf("home path leaked: %q", out)
16 }
17 if strings.Contains(out, "sk-secret") || strings.Contains(out, "abc.def") {
18 t.Fatalf("token leaked: %q", out)
19 }
20 if strings.Contains(out, "PATH=\""+home) {
21 t.Fatalf("PATH value leaked: %q", out)
22 }
23 if !strings.Contains(out, "<redacted>") && !strings.Contains(out, "Bearer <redacted>") {
24 t.Fatalf("expected redaction markers in %q", out)
25 }
26 }
27
28 func TestSanitizeErrTextRedactsHTTPBodyCredentialShapes(t *testing.T) {
29 // An HTTP transport error carries up to 4KB of raw response body; none of
30 // its credential shapes may survive into the shareable report.
31 in := `http 401: {"access_token":"sk-live-secret","x-api-key":"header-secret","password":"pw-secret"} Cookie: session=cookie-secret`
32 out := sanitizeErrText(in)
33 for _, leaked := range []string{"sk-live-secret", "header-secret", "pw-secret", "cookie-secret"} {
34 if strings.Contains(out, leaked) {
35 t.Fatalf("credential leaked %q in %q", leaked, out)
36 }
37 }
38 if !strings.Contains(out, "http 401") {
39 t.Fatalf("status context lost: %q", out)
40 }
41 }
42
43 func TestSanitizeErrTextRedactsVendorTokenShapes(t *testing.T) {
44 cases := []struct{ name, in, leaked string }{
45 {"jwt", "stderr: jwt eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.sflKxwRJSMeKKF2QT4fwpMeJf36POk6yJVadQssw5c", "eyJhbGciOiJIUzI1NiJ9"},
46 {"github", "stderr: fatal: ghp_abcdefghijklmnopqrstuvwxyz123456", "ghp_abcdefghijklmnopqrstuvwxyz123456"},
47 {"openai", "stderr: invalid key sk-proj-abcdefghijklmnop1234", "sk-proj-abcdefghijklmnop1234"},
48 {"colon-header", "http 403: x-api-key: header-secret-value", "header-secret-value"},
49 {"set-cookie", "http 401: Set-Cookie: sid=abc123def456ghi; Path=/", "abc123def456ghi"},
50 }
51 for _, tc := range cases {
52 out := sanitizeErrText(tc.in)
53 if strings.Contains(out, tc.leaked) {
54 t.Fatalf("%s: credential leaked in %q", tc.name, out)
55 }
56 }
57 }
58
58 lines GO