The vulnerability, identified as GHSA-xqxv-4jc2-x56x, stems from a failure to enforce client identity binding in several key OAuth2/OIDC grant flows within ZITADEL, a direct violation of RFC 6749. The analysis of the provided patch commit 0973b074b48816757c47fe732b06d2488d3d284c reveals that the application was missing critical validation to ensure the client exchanging a grant (authorization code, refresh token, or device code) was the same client that originally requested it.
The root cause was the absence of a client_id check in the functions responsible for processing these grants. An attacker who managed to steal a valid grant through external means (e.g., XSS, log leakage) could then use that grant with a different, potentially malicious, client registered on the same ZITADEL instance to gain unauthorized access to the victim's resources.
The patch rectifies this by introducing explicit client_id validation in the affected code paths:
- Authorization Code Exchange: The
(*Server).codeExchangeV1 function now verifies that the client_id of the requester matches the one stored in the authorization request.
- Refresh Token Grant: The
(*Commands).ExchangeOIDCSessionRefreshAndAccessToken function was modified to accept the requesting client's ID and delegate the check to refreshTokenComplianceChecker, which now compares it against the ID stored in the OIDC session.
- Device Authorization Flow: The
(*Commands).CreateOIDCSessionFromDeviceAuth function now validates that the client polling for the token is the same one that initiated the device authorization process.
By adding these checks, the patch ensures that grants are bound to the client they were issued to, effectively mitigating the reported vulnerability.