From 2aabe12e5329acc807c495445999e5591bdf982b Mon Sep 17 00:00:00 2001 From: hackerman <3372410+aeneasr@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:21:55 +0100 Subject: [PATCH] feat: add explicit config flag for secure cookies (#4180) Adds a new config flag for session and all other cookies. Falls back to the previous behavior of using the dev mode to decide if the cookie should be secure or not. --- driver/config/config.go | 16 ++++++++++++++++ driver/registry_default.go | 4 ++-- embedx/config.schema.json | 10 ++++++++++ x/nosurf.go | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index dd7a6a42f00d..a7e5a09580d0 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -110,6 +110,7 @@ const ( ViperKeyAdminTLSKeyPath = "serve.admin.tls.key.path" ViperKeySessionLifespan = "session.lifespan" ViperKeySessionSameSite = "session.cookie.same_site" + ViperKeySessionSecure = "session.cookie.secure" ViperKeySessionDomain = "session.cookie.domain" ViperKeySessionName = "session.cookie.name" ViperKeySessionPath = "session.cookie.path" @@ -124,6 +125,7 @@ const ( ViperKeyCookieSameSite = "cookies.same_site" ViperKeyCookieDomain = "cookies.domain" ViperKeyCookiePath = "cookies.path" + ViperKeyCookieSecure = "cookies.secure" ViperKeySelfServiceStrategyConfig = "selfservice.methods" ViperKeySelfServiceBrowserDefaultReturnTo = "selfservice." + DefaultBrowserReturnURL ViperKeyURLsAllowedReturnToDomains = "selfservice.allowed_return_urls" @@ -1384,6 +1386,13 @@ func (p *Config) SessionDomain(ctx context.Context) string { return p.GetProvider(ctx).String(ViperKeySessionDomain) } +func (p *Config) SessionCookieSecure(ctx context.Context) bool { + if !p.GetProvider(ctx).Exists(ViperKeySessionSecure) { + return !p.IsInsecureDevMode(ctx) + } + return p.GetProvider(ctx).Bool(ViperKeySessionSecure) +} + func (p *Config) CookieDomain(ctx context.Context) string { return p.GetProvider(ctx).String(ViperKeyCookieDomain) } @@ -1439,6 +1448,13 @@ func (p *Config) CookiePath(ctx context.Context) string { return p.GetProvider(ctx).String(ViperKeyCookiePath) } +func (p *Config) CookieSecure(ctx context.Context) bool { + if !p.GetProvider(ctx).Exists(ViperKeyCookieSecure) { + return !p.IsInsecureDevMode(ctx) + } + return p.GetProvider(ctx).Bool(ViperKeyCookieSecure) +} + func (p *Config) SelfServiceFlowLoginReturnTo(ctx context.Context, strategy string) *url.URL { return p.selfServiceReturnTo(ctx, ViperKeySelfServiceLoginAfter, strategy) } diff --git a/driver/registry_default.go b/driver/registry_default.go index 9f88c7375dd0..70e2994db5c9 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -527,7 +527,7 @@ func (m *RegistryDefault) CookieManager(ctx context.Context) sessions.StoreExact } cs := sessions.NewCookieStore(keys...) - cs.Options.Secure = !m.Config().IsInsecureDevMode(ctx) + cs.Options.Secure = m.Config().SessionCookieSecure(ctx) cs.Options.HttpOnly = true if domain := m.Config().SessionDomain(ctx); domain != "" { @@ -553,7 +553,7 @@ func (m *RegistryDefault) CookieManager(ctx context.Context) sessions.StoreExact func (m *RegistryDefault) ContinuityCookieManager(ctx context.Context) sessions.StoreExact { // To support hot reloading, this can not be instantiated only once. cs := sessions.NewCookieStore(m.Config().SecretsSession(ctx)...) - cs.Options.Secure = !m.Config().IsInsecureDevMode(ctx) + cs.Options.Secure = m.Config().CookieSecure(ctx) cs.Options.HttpOnly = true cs.Options.SameSite = http.SameSiteLaxMode return cs diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 78a92213d1cd..6a1cc1c90ede 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -2785,6 +2785,11 @@ "type": "string", "default": "/" }, + "secure": { + "title": "Session Cookie Secure Flag", + "description": "Sets the session secure flag. If unset, defaults to !dev mode.", + "type": "string" + }, "same_site": { "title": "HTTP Cookie Same Site Configuration", "description": "Sets the session and CSRF cookie SameSite.", @@ -2879,6 +2884,11 @@ "description": "Sets the session cookie path. Use with care! Overrides `cookies.path`.", "type": "string" }, + "secure": { + "title": "Session Cookie Secure Flag", + "description": "Sets the session secure flag. If unset, defaults to !dev mode.", + "type": "string" + }, "same_site": { "title": "Session Cookie SameSite Configuration", "description": "Sets the session cookie SameSite. Overrides `cookies.same_site`.", diff --git a/x/nosurf.go b/x/nosurf.go index 8169717fcda8..ce49f01d3cdd 100644 --- a/x/nosurf.go +++ b/x/nosurf.go @@ -138,7 +138,7 @@ func NosurfBaseCookieHandler(reg interface { config.Provider }) func(w http.ResponseWriter, r *http.Request) http.Cookie { return func(w http.ResponseWriter, r *http.Request) http.Cookie { - secure := !reg.Config().IsInsecureDevMode(r.Context()) + secure := reg.Config().CookieSecure(r.Context()) sameSite := reg.Config().CookieSameSiteMode(r.Context()) if !secure {