carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package apperr
2
3import "testing"
4
5func TestSanitize(t *testing.T) {
6 cases := map[string]string{
7 "user paul@tito.io not found": "user <email> not found",
8 "Authorization: Bearer abc.def-ghi": "Authorization: Bearer <redacted>",
9 "basic dXNlcjpwYXNz failed": "basic <redacted> failed",
10 "GET /x?token=abc123&y=1": "GET /x?token=<redacted>&y=1",
11 `{"password": "hunter2", "n": 3}`: `{"password": "<redacted>", "n": 3}`,
12 "api_key=sk-live-1234 ok": "api_key=<redacted> ok",
13 "digest 0123456789abcdef0123456789abcdef done": "digest <hex> done",
14 "b64 QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo0MTIzNA== ok": "b64 <hex> ok",
15 "short 4123 stays": "short 4123 stays",
16 "nothing here": "nothing here",
17 // Regression: a long run of letters/digits/"/"/"-"/"_" is not
18 // automatically a secret — a path or a long identifier must
19 // survive; only something hex- or base64-shaped is redacted.
20 "at Object.<anonymous> (/app/node_modules/express/lib/router/index.js:284:7)": "at Object.<anonymous> (/app/node_modules/express/lib/router/index.js:284:7)",
21 "internalServerErrorHandlerMiddlewareFactory": "internalServerErrorHandlerMiddlewareFactory",
22 "sess 0123456789abcdef0123456789abcdef0123456789abcdef done": "sess <hex> done",
23 // A JWT's dot-separated base64url segments: the "." breaks the
24 // candidate run into two tokens. The first (36 chars, mixes
25 // digit/upper/lower) clears the 32-char floor and is redacted;
26 // the second (19 chars) is below the floor and survives — see
27 // the report for why that is an accepted partial redaction here.
28 "jwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0 x": "jwt <hex>.eyJzdWIiOiIxMjM0In0 x",
29 }
30 for in, want := range cases {
31 if got := Sanitize(in); got != want {
32 t.Errorf("Sanitize(%q) = %q, want %q", in, got, want)
33 }
34 }
35}
36
37func TestSanitizePath(t *testing.T) {
38 cases := map[string]string{
39 "/reset/8f3a9c1e2b4d6f708a9b0c1d2e3f4a5b?x=1#frag": "/reset/:token",
40 "/users/paul@tito.io/edit": "/users/:token/edit",
41 "/items/550e8400-e29b-41d4-a716-446655440000": "/items/:token",
42 "/s/QUJDREVGR0hJSktMTU5PUFFSU1RV": "/s/:token",
43 "/blog/2024-review": "/blog/2024-review",
44 "/api/v2/orders/42": "/api/v2/orders/42",
45 "/": "/",
46 "": "/",
47 }
48 for in, want := range cases {
49 if got := SanitizePath(in); got != want {
50 t.Errorf("SanitizePath(%q) = %q, want %q", in, got, want)
51 }
52 }
53}
54