Sep 14, 2026·7 min read·7 visits
ZITADEL prior to v4.15.3 fails to validate that a subject token belongs to the requesting client or client project, and fails to ensure requested scopes are a subset of the original token scopes. This allows attackers to escalate privileges or bypass cross-client audience boundaries.
A security vulnerability in ZITADEL's backend implementation of the OAuth2 Token Exchange endpoint allows authenticated clients to perform scope escalation and cross-client audience bypass. Prior to version 4.15.3, the Token Exchange flow lacked crucial validation logic, enabling low-privilege tokens to be exchanged for high-privilege tokens or tokens valid within other client applications, violating the OAuth2 delegation model.
The OAuth2 Token Exchange protocol, defined in RFC 8693, allows a client application to exchange an existing security token for a new security token. This mechanism supports patterns such as impersonation, delegation, and token transitions within multi-tier architectures. In ZITADEL's architecture, the OpenID Connect (OIDC) backend handles these requests at the /oauth/v2/token endpoint when the grant type is set to urn:ietf:params:oauth:grant-type:token-exchange.
Prior to version 4.15.3, ZITADEL's backend implementation of the token exchange flow failed to perform two critical authorization boundaries. First, the server allowed clients to submit access tokens belonging to entirely different client applications or projects as the subject_token without validating ownership or target audience. Second, the server did not verify that the scopes requested in the exchange request were a subset of the scopes already granted in the source token.
This lack of validation permits a low-privilege token to serve as a stepping stone to acquire a high-privilege token, resulting in vertical privilege escalation. Additionally, because the client can use a token issued for a completely different client context, the security model suffers from a horizontal cross-client audience bypass. Organizations relying on ZITADEL to segregate permissions across disparate applications are particularly exposed to unauthorized data access and integrity violations.
The root cause of CVE-2026-56668 lies within the file internal/api/oidc/token_exchange.go in ZITADEL's core identity provider service. The verification logic is divided into two distinct failure points that collectively compromise the OAuth2 token delegation structure. The first failure point is located in the verifyExchangeToken function, which handles the validation of incoming subject_token and actor_token payloads.
When a standard access token (non-Personal Access Token) is provided, the backend validates the cryptographic signature and token expiration but does not verify whether the audience of the token aligns with the client application requesting the exchange. Specifically, the code omitted a call to match the token's audience list against the requesting client's ID or the project ID to which the client belongs. This allowed an authorized client to reuse an access token minted for another application to perform token exchange operations in its own domain.
The second failure point resides within the validateTokenExchangeScopes helper function. This function was designed to determine the final set of scopes assigned to the newly exchanged token. In a secure implementation, the requested scopes must be a mathematical subset of the scopes present in the original subject token. However, ZITADEL's implementation only defaulted to the subject's scopes if the requester left the requestedScopes list empty. When explicit scopes were requested, the server validated that the client was allowed to request those scopes generally, but completely bypassed checking whether they were authorized on the specific subject token being exchanged.
The vulnerability is resolved by modifying both validation vectors in internal/api/oidc/token_exchange.go. The following code block illustrates the patch applied to introduce target audience validation during token exchange processing:
// Prior to patch: standard access tokens bypassed audience matching
// Patched implementation:
if !token.isPAT {
if err = validateIntrospectionAudience(token.audience, client.GetID(), client.client.ProjectID); err != nil {
return nil, zerrors.ThrowPermissionDenied(err, "OIDC-zi9Y0", "Errors.TokenExchange.Token.Invalid")
}
}This ensures that the requesting client cannot supply a token meant for a different context. The second modification addresses the scope verification logic in validateTokenExchangeScopes. The comparison checks were refactored to enforce strict subset constraints:
// Patched scope validation loop
for _, scope := range requestedScopes {
if !slices.Contains(subjectScopes, scope) || !slices.Contains(actorScopes, scope) {
return nil, oidc.ErrInvalidScope().WithDescription("scope %q not found in subject or actor token", scope)
}
}The loop iterates through each element of requestedScopes. It utilizes Go's slices.Contains utility to assert that every requested scope is strictly bounded by both the subject token scopes and actor token scopes if present. Any deviation terminates the request immediately with an invalid scope error.
To exploit this vulnerability, an attacker requires valid client credentials or a low-privilege authenticated token to establish a base of operations on the vulnerable ZITADEL server. The attack is divided into two phases: token acquisition and token exchange exploitation. First, the attacker obtains an access token with minimal scopes, such as openid, from a target client application.
The attacker then constructs an HTTP POST request targeting the ZITADEL token endpoint. In this request, the attacker specifies the grant type as urn:ietf:params:oauth:grant-type:token-exchange and submits the low-privilege access token as the subject_token. In the scope parameter, the attacker includes highly privileged scopes, such as offline_access or backend administration scopes, which were not associated with the original token.
Upon receiving the request, the vulnerable server fails to confirm that the requested scopes are a subset of the subject token scopes. The server processes the request and issues a new access token containing the escalated scopes. The attacker can then utilize this newly minted token to access restricted administrative resources, completely bypassing the OAuth2 delegation boundary.
The impact of CVE-2026-56668 is classified as High, with a CVSS v3.1 base score of 8.1. The primary consequences of successful exploitation are privilege escalation and cross-client authorization bypass. Since ZITADEL acts as the centralized identity provider for organizations, a compromise of the authorization logic in its token endpoint directly undermines the security posture of all downstream applications relying on it.
An attacker who successfully exploits this vulnerability can escalate standard user permissions to administrative level permissions within any resource server that relies on ZITADEL-issued tokens. Furthermore, the cross-client audience bypass allows malicious or compromised client applications to hijack sessions and impersonate users across different application projects, violating multi-tenant isolation assumptions.
Despite the severity of this issue, the exploit complexity is Low, and the attack vector is Network, meaning it can be executed remotely without local system access or user interaction. There is currently no evidence of active exploitation in the wild, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog. However, the availability of clear proof-of-concept tests within the public repository increases the likelihood of opportunistic exploitation against unpatched deployments.
The official patch introduced in version 4.15.3 completely resolves the identified logical gaps. By incorporating validateIntrospectionAudience and enforcing a strict loop checking of scopes, ZITADEL has addressed both the audience bypass and the scope escalation attack paths. The regression tests added to the integration suite ensure that future updates will not reintroduce these logical omissions.
Organizations running ZITADEL versions older than 4.15.3 must upgrade their deployments to the latest patched version immediately. In scenarios where immediate patching is unfeasible, administrators should consider disabling the Token Exchange grant type for clients that do not strictly require it, thereby limiting the exposed attack surface.
Additionally, security teams should implement detection mechanisms. This includes monitoring authorization logs for token exchange requests that result in errors such as OIDC-zi9Y0 or invalid_scope, as these can indicate exploitation attempts. Network-level WAF rules can also be constructed to inspect payload parameters on /oauth/v2/token for token exchange requests and cross-reference them with threat intelligence indicators.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
ZITADEL ZITADEL | < 4.15.3 | 4.15.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 |
| Attack Vector | Network |
| CVSS Score | 8.1 |
| EPSS Score | 0.00413 (Percentile: 34.75%) |
| Impact | Privilege Escalation & Audience Bypass |
| Exploit Status | Proof of Concept available in tests |
| KEV Status | Not listed |
The software does not perform an authorization check when an actor attempts to access a resource or perform an action.
CVE-2026-46696 identifies a critical sandbox bypass vulnerability in the October CMS platform that affects the Twig template security policy when safe mode is enabled. An authenticated backend user with permissions to modify CMS markup templates can chain unrestricted session store method access with Eloquent database query forwarding omissions. This chain allows the attacker to execute arbitrary raw SQL queries to read system secrets and subsequently write those secrets directly to the active session payload, achieving unauthorized administrative privilege escalation.
A security vulnerability in October Content Management System (CMS) involves the deserialization of untrusted data (CWE-502) within the backend SessionMaker trait. Prior to the patched versions, October CMS stored widget session states as base64-encoded serialized PHP objects. When loading these states, the application consumed them using unserialize() without enforcing class restrictions (allowed_classes). In configurations where cms.safe_mode is enabled to sandbox users with markup editor privileges, an attacker can exploit this behavior to instantiate arbitrary PHP classes and execute arbitrary code via accessible gadget chains.
CVE-2026-76081 is a logical vulnerability in ZITADEL's role cascading logic where updating a Project Grant to drop multiple adjacent roles simultaneously fails to clean up associated User Grants due to an in-place slice mutation error in Go.
This report provides a technical analysis of GHSA-2XMM-M4WV-3FJH, an incomplete scheme validation vulnerability in the image resizing utility of October CMS. By exploiting this flaw, authenticated or privileged users can pass dangerous URI schemes to trigger deserialization of untrusted metadata.
An authentication bypass vulnerability in ESPHome Device Builder Dashboard allows unauthenticated remote attackers to gain administrative access. The flaw is caused by a backward compatibility break during an environment variable rename that silently disables dashboard authentication upon upgrade.
A critical prototype pollution vulnerability was discovered in the confetti yayson library prior to version 4.3.0. The library deserializes JSON:API structures into internal cache dictionaries mapped with standard JavaScript objects. An attacker can control the cache keys by supplying '__proto__' in properties like type or id, modifying the prototype of all JavaScript objects process-wide.