Repository navigation
Description
Description
CVE-2026-37977: When using the UMA token endpoint, Keycloak sets the Access-Control-Allow-Origin response header based on the azp claim from a client-provided JWT before validating the JWT signature. While the token grant itself is correctly rejected during validation, the CORS header has already been set in the response.
This allows a client to control which origin can read the error response cross-origin. The impact is limited to reading error messages - no tokens or user data are exposed.
Prerequisites:
- Client must be configured with
webOrigins: ["*"](non-default configuration) - Only affects error responses, not successful token grants
Version Affected
26.5.6 and potentially other versions
Steps to Reproduce
- Configure a Keycloak client with
webOrigins: ["*"] - Create a JWT with the
azpclaim set to any origin (e.g.,https://example.com) - Sign the JWT with any key (signature validation will fail later)
- Send a POST request to
/realms/{realm}/protocol/openid-connect/tokenwith:grant_type=urn:ietf:params:oauth:grant-type:uma-ticket- Include the crafted JWT
- Inspect the response headers
Expected Behavior
The Access-Control-Allow-Origin header should only be set after JWT signature validation, or should be based on the client's configured origins rather than the unverified azp claim.
Actual Behavior
The Access-Control-Allow-Origin header reflects the value from the azp claim before signature verification, allowing the error response to be read cross-origin from any specified domain.
Additional Context
This issue has been assigned CVE-2026-37977 for tracking purposes.
The practical impact is limited because:
- Only error responses are affected
- No tokens or user data are exposed
- Requires non-default client configuration
- The token grant itself is correctly rejected
This issue was originally tracked in the private repository. Migrated by @ahus1.
Activity
ahus1 commentedon Apr 14, 2026
@pedroigor - please schedule this in your team.
I've assigned you to this issue for the time being to do additional labeling and planning.
pedroigor commentedon Apr 15, 2026
Resuming from:
ValeriaEpifanova commentedon Apr 28, 2026
@ahus1 @pedroigor Hello everyone! According to steps of reproducing if we open PermissionGrantType class we can see that CORS sets before throwing the CorsErrorResponseException. In case when token is invalid.
The question is should we set CORS only when client "web origins" claim doesn't contain "*"?
For example something like
Set clientOrigin = WebOriginsUtils.resolveValidWebOrigins(session, client);
if (!clientOrigin.contains("*")) {
cors.allowedOrigins(session, client);
}
pedroigor commentedon May 27, 2026
@ValeriaEpifanova From the last comment from @stianst, we should resolve the allowed origins from the bearer token because tokens issued by Keycloak will have a specific claim with the web origins.
pedroigor commentedon May 29, 2026
@ValeriaEpifanova Sent @ValeriaEpifanova.
6 remaining items
[CVE-2026-37977] CORS Access-Control-Allow-Origin reflected from unve…
[CVE-2026-37977] CORS Access-Control-Allow-Origin reflected from unve…
[CVE-2026-37977] CORS Access-Control-Allow-Origin reflected from unve…