Skip to content

Commit cabb0e8

Browse files
authored
Merge pull request #131 from soulteary/test/fix-TestHandlerAPISavePathTraversal
test: fix TestHandlerAPISavePathTraversal
2 parents 174a985 + 11f7381 commit cabb0e8

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

internal/configui/configui.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,12 @@ func runSave(w http.ResponseWriter, r *http.Request, writeDir string) {
293293
writeJSONError(w, http.StatusBadRequest, "invalid json: "+err.Error())
294294
return
295295
}
296-
base := filepath.Base(strings.TrimSpace(req.Filename))
296+
trimmed := strings.TrimSpace(req.Filename)
297+
if strings.Contains(trimmed, "..") {
298+
writeJSONError(w, http.StatusBadRequest, "invalid filename")
299+
return
300+
}
301+
base := filepath.Base(trimmed)
297302
if base == "" || base == "." {
298303
writeJSONError(w, http.StatusBadRequest, "filename is required")
299304
return

internal/configui/configui_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,16 +403,19 @@ func TestHandlerAPISavePathTraversal(t *testing.T) {
403403
if err != nil {
404404
t.Fatalf("Handler: %v", err)
405405
}
406-
body := `{"filename":"../../../etc/passwd","content":"x"}`
406+
// Use a unique name under a path traversal so we only fail if we created it (../etc/passwd exists on Unix)
407+
traversalName := "webhook-path-traversal-" + filepath.Base(tmp) + ".yaml"
408+
body := `{"filename":"../../../etc/` + traversalName + `","content":"x"}`
407409
req := httptest.NewRequest(http.MethodPost, "http://test/api/save", bytes.NewReader([]byte(body)))
408410
req.Header.Set("Content-Type", "application/json")
409411
w := httptest.NewRecorder()
410412
h.ServeHTTP(w, req)
411413
if w.Code != http.StatusBadRequest {
412414
t.Errorf("POST /api/save with path traversal: status %d, want 400", w.Code)
413415
}
414-
_, err = os.Stat(filepath.Join(tmp, "../../../etc/passwd"))
415-
if err == nil {
416+
// Resolve path: must not create file outside writeDir (this path would only exist if we had a bug)
417+
targetPath := filepath.Clean(filepath.Join(tmp, "..", "..", "..", "etc", traversalName))
418+
if _, err := os.Stat(targetPath); err == nil {
416419
t.Error("path traversal must not create file outside writeDir")
417420
}
418421
}

0 commit comments

Comments
 (0)