ZITADEL Vulnerable to Session Information Leakage
Description
ZITADEL is an open-source identity infrastructure tool. ZITADEL provides users the ability to list all user sessions of the current user agent (browser). Starting in version 2.53.0 and prior to versions 2.53.8, 2.54.5, and 2.55.1, due to a missing check, user sessions without that information (e.g. when created though the session service) were incorrectly listed exposing potentially other user's sessions. Versions 2.55.1, 2.54.5, and 2.53.8 contain a fix for the issue. There is no workaround since a patch is already available.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/zitadel/zitadelGo | >= 2.0.0, < 2.53.8 | 2.53.8 |
github.com/zitadel/zitadelGo | >= 2.54.0, < 2.54.5 | 2.54.5 |
github.com/zitadel/zitadelGo | >= 2.55.0, < 2.55.1 | 2.55.1 |
Affected products
1Patches
4c2093ce01507fix: correctly set user agent / fingerprint id on user sessions (#8231)
5 files changed · +13 −12
internal/api/oidc/auth_request.go+1 −1 modified@@ -555,7 +555,7 @@ func (s *Server) authResponseToken(authReq *AuthRequest, authorizer op.Authorize authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/oidc/token_code.go+1 −1 modified@@ -81,7 +81,7 @@ func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.A authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/ui/login/device_auth.go+1 −1 modified@@ -162,7 +162,7 @@ func (l *Login) handleDeviceAuthAction(w http.ResponseWriter, r *http.Request) { action := mux.Vars(r)["action"] switch action { case deviceAuthAllowed: - _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.BrowserInfo.ToUserAgent()) + _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.ToUserAgent()) case deviceAuthDenied: _, err = l.command.CancelDeviceAuth(r.Context(), authDev.DeviceCode, domain.DeviceAuthCanceledDenied) default:
internal/domain/browser_info.go+9 −8 modified@@ -23,14 +23,15 @@ func BrowserInfoFromRequest(r *net_http.Request) *BrowserInfo { } } -func (b *BrowserInfo) ToUserAgent() *UserAgent { - if b == nil { - return nil +func (a *AuthRequest) ToUserAgent() *UserAgent { + agent := &UserAgent{ + FingerprintID: &a.AgentID, } - return &UserAgent{ - FingerprintID: &b.UserAgent, - IP: b.RemoteIP, - Description: &b.UserAgent, - Header: b.Header, + if a.BrowserInfo == nil { + return agent } + agent.IP = a.BrowserInfo.RemoteIP + agent.Description = &a.BrowserInfo.UserAgent + agent.Header = a.BrowserInfo.Header + return agent }
internal/user/repository/view/user_sessions_by_user_agent.sql+1 −1 modified@@ -22,6 +22,6 @@ FROM auth.user_sessions s LEFT JOIN projections.users12 u ON s.user_id = u.id AND s.instance_id = u.instance_id LEFT JOIN projections.users12_humans h ON s.user_id = h.user_id AND s.instance_id = h.instance_id LEFT JOIN projections.login_names3 l ON s.user_id = l.user_id AND s.instance_id = l.instance_id AND l.is_primary = true -WHERE (s.user_agent_id = $1) +WHERE (s.user_agent_id = $1 and s.user_agent_id <> '') AND (s.instance_id = $2) ; \ No newline at end of file
4a262e42abacfix: correctly set user agent / fingerprint id on user sessions (#8231)
5 files changed · +13 −12
internal/api/oidc/auth_request.go+1 −1 modified@@ -555,7 +555,7 @@ func (s *Server) authResponseToken(authReq *AuthRequest, authorizer op.Authorize authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/oidc/token_code.go+1 −1 modified@@ -81,7 +81,7 @@ func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.A authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/ui/login/device_auth.go+1 −1 modified@@ -162,7 +162,7 @@ func (l *Login) handleDeviceAuthAction(w http.ResponseWriter, r *http.Request) { action := mux.Vars(r)["action"] switch action { case deviceAuthAllowed: - _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.BrowserInfo.ToUserAgent()) + _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.ToUserAgent()) case deviceAuthDenied: _, err = l.command.CancelDeviceAuth(r.Context(), authDev.DeviceCode, domain.DeviceAuthCanceledDenied) default:
internal/domain/browser_info.go+9 −8 modified@@ -23,14 +23,15 @@ func BrowserInfoFromRequest(r *net_http.Request) *BrowserInfo { } } -func (b *BrowserInfo) ToUserAgent() *UserAgent { - if b == nil { - return nil +func (a *AuthRequest) ToUserAgent() *UserAgent { + agent := &UserAgent{ + FingerprintID: &a.AgentID, } - return &UserAgent{ - FingerprintID: &b.UserAgent, - IP: b.RemoteIP, - Description: &b.UserAgent, - Header: b.Header, + if a.BrowserInfo == nil { + return agent } + agent.IP = a.BrowserInfo.RemoteIP + agent.Description = &a.BrowserInfo.UserAgent + agent.Header = a.BrowserInfo.Header + return agent }
internal/user/repository/view/user_sessions_by_user_agent.sql+1 −1 modified@@ -22,6 +22,6 @@ FROM auth.user_sessions s LEFT JOIN projections.users12 u ON s.user_id = u.id AND s.instance_id = u.instance_id LEFT JOIN projections.users12_humans h ON s.user_id = h.user_id AND s.instance_id = h.instance_id LEFT JOIN projections.login_names3 l ON s.user_id = l.user_id AND s.instance_id = l.instance_id AND l.is_primary = true -WHERE (s.user_agent_id = $1) +WHERE (s.user_agent_id = $1 and s.user_agent_id <> '') AND (s.instance_id = $2) ; \ No newline at end of file
d04f208486a4fix: correctly set user agent / fingerprint id on user sessions (#8231)
5 files changed · +13 −12
internal/api/oidc/auth_request.go+1 −1 modified@@ -555,7 +555,7 @@ func (s *Server) authResponseToken(authReq *AuthRequest, authorizer op.Authorize authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/oidc/token_code.go+1 −1 modified@@ -81,7 +81,7 @@ func (s *Server) codeExchangeV1(ctx context.Context, client *Client, req *oidc.A authReq.AuthTime, authReq.GetNonce(), authReq.PreferredLanguage, - authReq.BrowserInfo.ToUserAgent(), + authReq.ToUserAgent(), domain.TokenReasonAuthRequest, nil, slices.Contains(scope, oidc.ScopeOfflineAccess),
internal/api/ui/login/device_auth.go+1 −1 modified@@ -162,7 +162,7 @@ func (l *Login) handleDeviceAuthAction(w http.ResponseWriter, r *http.Request) { action := mux.Vars(r)["action"] switch action { case deviceAuthAllowed: - _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.BrowserInfo.ToUserAgent()) + _, err = l.command.ApproveDeviceAuth(r.Context(), authDev.DeviceCode, authReq.UserID, authReq.UserOrgID, authReq.UserAuthMethodTypes(), authReq.AuthTime, authReq.PreferredLanguage, authReq.ToUserAgent()) case deviceAuthDenied: _, err = l.command.CancelDeviceAuth(r.Context(), authDev.DeviceCode, domain.DeviceAuthCanceledDenied) default:
internal/domain/browser_info.go+9 −8 modified@@ -23,14 +23,15 @@ func BrowserInfoFromRequest(r *net_http.Request) *BrowserInfo { } } -func (b *BrowserInfo) ToUserAgent() *UserAgent { - if b == nil { - return nil +func (a *AuthRequest) ToUserAgent() *UserAgent { + agent := &UserAgent{ + FingerprintID: &a.AgentID, } - return &UserAgent{ - FingerprintID: &b.UserAgent, - IP: b.RemoteIP, - Description: &b.UserAgent, - Header: b.Header, + if a.BrowserInfo == nil { + return agent } + agent.IP = a.BrowserInfo.RemoteIP + agent.Description = &a.BrowserInfo.UserAgent + agent.Header = a.BrowserInfo.Header + return agent }
internal/user/repository/view/user_sessions_by_user_agent.sql+1 −1 modified@@ -22,6 +22,6 @@ FROM auth.user_sessions s LEFT JOIN projections.users13 u ON s.user_id = u.id AND s.instance_id = u.instance_id LEFT JOIN projections.users13_humans h ON s.user_id = h.user_id AND s.instance_id = h.instance_id LEFT JOIN projections.login_names3 l ON s.user_id = l.user_id AND s.instance_id = l.instance_id AND l.is_primary = true -WHERE (s.user_agent_id = $1) +WHERE (s.user_agent_id = $1 and s.user_agent_id <> '') AND (s.instance_id = $2) ; \ No newline at end of file
08a75635d216Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
12- github.com/advisories/GHSA-cvw9-c57h-3397ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-39683ghsaADVISORY
- discord.com/channels/927474939156643850/1254096852937347153ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/commit/4a262e42abac2208b02fefaf68ba1a5121649f04ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/commit/c2093ce01507ca8fc811609ff5d391693360c3daghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/commit/d04f208486a418a45b884b9ca8433e5ad9790d73ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/issues/8213ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/pull/8231ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/releases/tag/v2.53.8ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/releases/tag/v2.54.5ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/releases/tag/v2.55.1ghsax_refsource_MISCWEB
- github.com/zitadel/zitadel/security/advisories/GHSA-cvw9-c57h-3397ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.