From 185daab909c26f0b33807f471f6ebc46ac250240 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 8 Feb 2026 12:05:09 -0800 Subject: [PATCH] fix: set Secure flag on session cookie in production mode (closes #5) --- internal/service/auth/auth.go | 1 + internal/service/auth/auth_test.go | 70 ++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/internal/service/auth/auth.go b/internal/service/auth/auth.go index 352cbf1..94447e9 100644 --- a/internal/service/auth/auth.go +++ b/internal/service/auth/auth.go @@ -73,6 +73,7 @@ func New(_ fx.Lifecycle, params ServiceParams) (*Service, error) { Path: "/", MaxAge: sessionMaxAgeSeconds, HttpOnly: true, + Secure: !params.Config.Debug, SameSite: http.SameSiteLaxMode, } diff --git a/internal/service/auth/auth_test.go b/internal/service/auth/auth_test.go index 29aa80d..9ca9430 100644 --- a/internal/service/auth/auth_test.go +++ b/internal/service/auth/auth_test.go @@ -2,6 +2,8 @@ package auth_test import ( "context" + "net/http" + "net/http/httptest" "path/filepath" "testing" @@ -68,6 +70,74 @@ func setupTestService(t *testing.T) (*auth.Service, func()) { return svc, cleanup } +func TestSessionCookieSecureFlag(testingT *testing.T) { + testingT.Parallel() + + testingT.Run("secure flag is true when debug is false", func(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + + globals.SetAppname("upaas-test") + globals.SetVersion("test") + + globalsInst, err := globals.New(fx.Lifecycle(nil)) + require.NoError(t, err) + + loggerInst, err := logger.New( + fx.Lifecycle(nil), + logger.Params{Globals: globalsInst}, + ) + require.NoError(t, err) + + cfg := &config.Config{ + Port: 8080, + DataDir: tmpDir, + SessionSecret: "test-secret-key-at-least-32-chars", + Debug: false, + } + + dbInst, err := database.New(fx.Lifecycle(nil), database.Params{ + Logger: loggerInst, + Config: cfg, + }) + require.NoError(t, err) + + svc, err := auth.New(fx.Lifecycle(nil), auth.ServiceParams{ + Logger: loggerInst, + Config: cfg, + Database: dbInst, + }) + require.NoError(t, err) + + // Create user and session, check cookie has Secure flag + _, err = svc.CreateUser(context.Background(), "admin", "password123") + require.NoError(t, err) + + user, err := svc.Authenticate(context.Background(), "admin", "password123") + require.NoError(t, err) + + recorder := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodGet, "/", nil) + + err = svc.CreateSession(recorder, request, user) + require.NoError(t, err) + + cookies := recorder.Result().Cookies() + require.NotEmpty(t, cookies) + + var sessionCookie *http.Cookie + for _, c := range cookies { + if c.Name == "upaas_session" { + sessionCookie = c + break + } + } + require.NotNil(t, sessionCookie, "session cookie should exist") + assert.True(t, sessionCookie.Secure, "session cookie should have Secure flag in production mode") + }) +} + func TestHashPassword(testingT *testing.T) { testingT.Parallel()