diff --git a/driver/registry_default.go b/driver/registry_default.go index 62a089edb233..247e59d8d4bf 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -2,6 +2,7 @@ package driver import ( "context" + "crypto/sha256" "net/http" "strings" "sync" @@ -426,7 +427,13 @@ func (m *RegistryDefault) SelfServiceErrorHandler() *errorx.Handler { } func (m *RegistryDefault) CookieManager(ctx context.Context) sessions.StoreExact { - cs := sessions.NewCookieStore(m.Config(ctx).SecretsSession()...) + var keys [][]byte + for _, k := range m.Config(ctx).SecretsSession() { + encrypt := sha256.Sum256(k) + keys = append(keys, k, encrypt[:]) + } + + cs := sessions.NewCookieStore(keys...) cs.Options.Secure = !m.Config(ctx).IsInsecureDevMode() cs.Options.HttpOnly = true diff --git a/session/manager_http_test.go b/session/manager_http_test.go index 5641534feb69..f754ee0c55ba 100644 --- a/session/manager_http_test.go +++ b/session/manager_http_test.go @@ -205,6 +205,31 @@ func TestManagerHTTP(t *testing.T) { assert.EqualValues(t, http.StatusOK, res.StatusCode) }) + t.Run("case=key rotation", func(t *testing.T) { + original := conf.Source().Strings(config.ViperKeySecretsCookie) + t.Cleanup(func() { + conf.MustSet(config.ViperKeySecretsCookie, original) + }) + conf.MustSet(config.ViperKeySessionLifespan, "1m") + conf.MustSet(config.ViperKeySecretsCookie, []string{"foo"}) + + i := identity.Identity{Traits: []byte("{}")} + require.NoError(t, reg.PrivilegedIdentityPool().CreateIdentity(context.Background(), &i)) + s, _ = session.NewActiveSession(&i, conf, time.Now(), identity.CredentialsTypePassword) + + c := testhelpers.NewClientWithCookies(t) + testhelpers.MockHydrateCookieClient(t, c, pts.URL+"/session/set") + + res, err := c.Get(pts.URL + "/session/get") + require.NoError(t, err) + assert.EqualValues(t, http.StatusOK, res.StatusCode) + + conf.MustSet(config.ViperKeySecretsCookie, []string{"bar", "foo"}) + res, err = c.Get(pts.URL + "/session/get") + require.NoError(t, err) + assert.EqualValues(t, http.StatusOK, res.StatusCode) + }) + t.Run("case=no panic on invalid cookie name", func(t *testing.T) { conf.MustSet(config.ViperKeySessionLifespan, "1m") conf.MustSet(config.ViperKeySessionName, "$%˜\"")