diff --git a/CHANGELOG-6.md b/CHANGELOG-6.md index 9a8eccde0..8a9a7494b 100644 --- a/CHANGELOG-6.md +++ b/CHANGELOG-6.md @@ -9,8 +9,8 @@ Versioning](http://semver.org/spec/v2.0.0.html). ## [6.11.1] - 2024-09-12 ### Changed -- Added TTl to each entry in user-session within etcd -- TTl value is 6 minutes +- ADD TTL to each user session in the etcd data store to prevent leak. +- TTl value is DefaultAccessTokenLifeSpan + 1 minute ## [6.11.0] - 2024-01-31 diff --git a/backend/authentication/jwt/jwt.go b/backend/authentication/jwt/jwt.go index 09c65d526..7e2d513ec 100644 --- a/backend/authentication/jwt/jwt.go +++ b/backend/authentication/jwt/jwt.go @@ -26,7 +26,7 @@ const ( ) var ( - defaultAccessTokenLifespan = 5 * time.Minute + DefaultAccessTokenLifespan = 5 * time.Minute defaultRefreshTokenLifespan = 12 * time.Hour secret []byte privateKey *ecdsa.PrivateKey @@ -58,7 +58,7 @@ func AccessToken(claims *corev2.Claims) (*jwt.Token, string, error) { claims.Id = jti // Add an expiration to the token - claims.ExpiresAt = time.Now().Add(defaultAccessTokenLifespan).Unix() + claims.ExpiresAt = time.Now().Add(DefaultAccessTokenLifespan).Unix() token := jwt.NewWithClaims(signingMethod, claims) @@ -78,7 +78,7 @@ func AccessToken(claims *corev2.Claims) (*jwt.Token, string, error) { return token, tokenString, nil } -// NewClaims creates new claim based on username +:q// NewClaims creates new claim based on username func NewClaims(user *corev2.User) (*corev2.Claims, error) { // Create a unique identifier for the token jti, err := GenJTI() @@ -91,7 +91,7 @@ func NewClaims(user *corev2.User) (*corev2.Claims, error) { // library's documentation. We should replace its usage with // RegisteredClaims. StandardClaims: jwt.StandardClaims{ - ExpiresAt: time.Now().Add(defaultAccessTokenLifespan).Unix(), + ExpiresAt: time.Now().Add(DefaultAccessTokenLifespan).Unix(), Id: jti, Subject: user.Username, }, diff --git a/backend/authentication/jwt/jwt_test.go b/backend/authentication/jwt/jwt_test.go index 0abc6ba5e..bbfea6756 100644 --- a/backend/authentication/jwt/jwt_test.go +++ b/backend/authentication/jwt/jwt_test.go @@ -121,7 +121,7 @@ func TestValidateTokenError(t *testing.T) { assert.NoError(t, err) // The token should expire after the expiration time - testTime.Set(time.Now().Add(defaultAccessTokenLifespan + time.Hour)) + testTime.Set(time.Now().Add(DefaultAccessTokenLifespan + time.Hour)) _, err = ValidateToken(tokenString) assert.Error(t, err) } @@ -134,7 +134,7 @@ func TestValidateExpiredToken(t *testing.T) { _, tokenString, _ := AccessToken(claims) // Wait for the token to expire - testTime.Set(time.Now().Add(defaultAccessTokenLifespan + time.Second)) + testTime.Set(time.Now().Add(DefaultAccessTokenLifespan + time.Second)) _, err := ValidateExpiredToken(tokenString) assert.NoError(t, err, "An expired token should not be considered as invalid") } @@ -158,7 +158,7 @@ func TestValidateExpiredTokenInvalid(t *testing.T) { _, tokenString, _ := AccessToken(claims) // The token will expire - testTime.Set(time.Now().Add(defaultAccessTokenLifespan + time.Second)) + testTime.Set(time.Now().Add(DefaultAccessTokenLifespan + time.Second)) // Modify the secret so it's no longer valid secret = []byte("qux") diff --git a/backend/store/etcd/session.go b/backend/store/etcd/session.go index 8dc8ac715..2af98e839 100644 --- a/backend/store/etcd/session.go +++ b/backend/store/etcd/session.go @@ -3,7 +3,7 @@ package etcd import ( "context" "fmt" - + "github.com/sensu/sensu-go/backend/authentication/jwt" "github.com/sensu/sensu-go/backend/store" "go.etcd.io/etcd/client/v3" ) @@ -30,9 +30,12 @@ func (s *Store) GetSession(ctx context.Context, username, sessionID string) (str } // UpdateSession applies the supplied state to the session uniquely identified -// by the given username and session ID and TTL of 6 minutes added considering access token expires in 5 minutes +// by the given username and session ID with attached lease for TTL of the key func (s *Store) UpdateSession(ctx context.Context, username, sessionID, state string) error { - leaseResp, err := s.client.Grant(ctx, 60*6) + + leaseDuration := jwt.DefaultAccessTokenLifespan + ttl := int64(leaseDuration.Minutes()+1) * 60 + leaseResp, err := s.client.Grant(ctx, ttl) if err != nil { return fmt.Errorf("%s", err) }