fix(02-03): scrub short captured ids only at token boundaries

Numeric seed ids like 1 were substring-replaced through /api/v1 paths
and 15-style JSON integers. Keep ReplaceAll for long secrets and isolate
short values so the corpus stays replayable.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-09-17 12:47:38 +02:00
parent 4451c2f39f
commit 1ea3c59055
2 changed files with 78 additions and 2 deletions

View File

@@ -124,7 +124,7 @@ func TestScrubRejectsUnclassifiedAndPersistsVars(t *testing.T) {
t.Fatalf("mode %o", st.Mode().Perm())
}
unknown := Step{
ID: "bad",
ID: "bad",
Response: Response{Body: Body(`{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJib2IifQ.otherSignatureValue99"}`)},
}
if err := ScrubStep(store, &unknown); err == nil {
@@ -271,3 +271,43 @@ func post(t *testing.T, url, session, ct, body string) {
t.Fatalf("%s: %d", url, resp.StatusCode)
}
}
func TestScrubShortNumericIDsDoNotCorruptPaths(t *testing.T) {
store, err := OpenStore("")
if err != nil {
t.Fatal(err)
}
store.Set("id:alice", "1")
store.Set("id:genre", "4")
step := Step{
ID: "genres",
Request: Request{
Method: http.MethodGet,
Path: "/_fonoteka/api/v1/genres",
Headers: map[string]string{"Authorization": "Bearer x"},
},
Response: Response{
Status: 200,
Body: Body(`{"data":[{"id":1,"name":"Rock","album_count":0},{"id":15,"name":"Latin"},{"id":4,"name":"Jazz","album_count":1}]}`),
},
}
if err := ScrubStep(store, &step); err != nil {
t.Fatal(err)
}
if step.Request.Path != "/_fonoteka/api/v1/genres" {
t.Fatalf("path corrupted: %s", step.Request.Path)
}
body := string(step.Response.Body)
if !strings.Contains(body, `"id":{{id:alice}}`) {
t.Fatalf("id 1 not isolated: %s", body)
}
if !strings.Contains(body, `"id":15`) {
t.Fatalf("id 15 must stay intact: %s", body)
}
if !strings.Contains(body, `"id":{{id:genre}}`) {
t.Fatalf("id 4 not isolated: %s", body)
}
if strings.Contains(body, "{{id:alice}}5") || strings.Contains(body, "v{{id:alice}}") {
t.Fatalf("substring replace leaked: %s", body)
}
}