mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-11-09 08:55:36 +00:00
fix(security): scope logout invalidation keys to the middleware instance
Back-channel logout keys for sub, sid and jti had no issuer or client in them, in a cache shared by every instance. A logout for user u1 in one realm logged out u1 in another, and an equal jti in two realms looked like a replay. Keys now carry the instance prefix. An instance without a prefix keeps the old key.
This commit is contained in:
@@ -617,6 +617,11 @@ func (t *TraefikOidc) isSessionInvalidated(sid, sub string, sessionCreatedAt tim
|
|||||||
|
|
||||||
// buildSessionInvalidationKey creates a cache key for session invalidation
|
// buildSessionInvalidationKey creates a cache key for session invalidation
|
||||||
func (t *TraefikOidc) buildSessionInvalidationKey(keyType, value string) string {
|
func (t *TraefikOidc) buildSessionInvalidationKey(keyType, value string) string {
|
||||||
|
// sub, sid and jti are unique only within an issuer; the cache is shared by
|
||||||
|
// every instance, so scope the key to this instance's provider and client.
|
||||||
|
if ns := t.tokenCache.Namespace(); ns != "" {
|
||||||
|
return fmt.Sprintf("session_invalidation:%s|%s:%s", ns, keyType, value)
|
||||||
|
}
|
||||||
return fmt.Sprintf("session_invalidation:%s:%s", keyType, value)
|
return fmt.Sprintf("session_invalidation:%s:%s", keyType, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package traefikoidc
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSessionInvalidationKeyScopedPerInstance(t *testing.T) {
|
||||||
|
a := &TraefikOidc{tokenCache: &TokenCache{}}
|
||||||
|
b := &TraefikOidc{tokenCache: &TokenCache{}}
|
||||||
|
a.tokenCache.SetNamespace("https://kc/realms/a|c|c")
|
||||||
|
b.tokenCache.SetNamespace("https://kc/realms/b|c|c")
|
||||||
|
for _, kind := range []string{"sub", "sid", "jti"} {
|
||||||
|
if a.buildSessionInvalidationKey(kind, "u1") == b.buildSessionInvalidationKey(kind, "u1") {
|
||||||
|
t.Errorf("%s key shared across issuers", kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if got := (&TraefikOidc{}).buildSessionInvalidationKey("sub", "u1"); got != "session_invalidation:sub:u1" {
|
||||||
|
t.Errorf("namespace-less key changed: %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user