From 1758eea94853f4c2a6fe2ee829a43267f2b14c28 Mon Sep 17 00:00:00 2001 From: danmobot Date: Tue, 23 Jun 2026 02:24:53 +0100 Subject: [PATCH] test: cover launcher setup csrf guard --- web/backend/api/auth_csrf_test.go | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 web/backend/api/auth_csrf_test.go diff --git a/web/backend/api/auth_csrf_test.go b/web/backend/api/auth_csrf_test.go new file mode 100644 index 00000000..50b0fefd --- /dev/null +++ b/web/backend/api/auth_csrf_test.go @@ -0,0 +1,63 @@ +package api + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestLauncherAuthSetupRejectsCrossSiteFirstRun(t *testing.T) { + store := &fakePasswordStore{} + mux := http.NewServeMux() + RegisterLauncherAuthRoutes(mux, LauncherAuthRouteOpts{ + SessionCookie: "session-cookie-value", + PasswordStore: store, + }) + + rec := httptest.NewRecorder() + req := httptest.NewRequest( + http.MethodPost, + "http://127.0.0.1:18800/api/auth/setup", + strings.NewReader(`{"password":"CrossSitePwn123!","confirm":"CrossSitePwn123!"}`), + ) + req.Header.Set("Origin", "https://evil.example") + req.Header.Set("Referer", "https://evil.example/attack") + req.Header.Set("Sec-Fetch-Site", "cross-site") + req.Header.Set("Content-Type", "application/json") + mux.ServeHTTP(rec, req) + + if rec.Code != http.StatusForbidden { + t.Fatalf("cross-site setup code = %d body=%s", rec.Code, rec.Body.String()) + } + if store.initialized || store.password != "" { + t.Fatalf("cross-site setup mutated store: initialized=%v password=%q", store.initialized, store.password) + } +} + +func TestLauncherAuthSetupAllowsSameOriginFirstRun(t *testing.T) { + store := &fakePasswordStore{} + mux := http.NewServeMux() + RegisterLauncherAuthRoutes(mux, LauncherAuthRouteOpts{ + SessionCookie: "session-cookie-value", + PasswordStore: store, + }) + + rec := httptest.NewRecorder() + req := httptest.NewRequest( + http.MethodPost, + "http://127.0.0.1:18800/api/auth/setup", + strings.NewReader(`{"password":"LocalSetup123!","confirm":"LocalSetup123!"}`), + ) + req.Header.Set("Origin", "http://127.0.0.1:18800") + req.Header.Set("Sec-Fetch-Site", "same-origin") + req.Header.Set("Content-Type", "application/json") + mux.ServeHTTP(rec, req) + + if rec.Code != http.StatusOK { + t.Fatalf("same-origin setup code = %d body=%s", rec.Code, rec.Body.String()) + } + if !store.initialized || store.password != "LocalSetup123!" { + t.Fatalf("same-origin setup store: initialized=%v password=%q", store.initialized, store.password) + } +}