Bug 2499592 (CVE-2026-15572)
| Summary: | CVE-2026-15572 keycloak-services: keycloak-services: DCR protocol mapper type-swap policy bypass allows privilege escalation | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security DevOps Team <prodsec-dev> |
| Status: | NEW --- | QA Contact: | |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | unspecified | CC: | 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's Dynamic Client Registration (DCR) security policy management. The "Allowed Protocol Mapper Types" policy, which restricts which types of data mappers a client can use, fails to re-validate the mapper type during a client update if the mapper's configuration remains unchanged. An attacker with client registration privileges can exploit this by first registering an allowed mapper type with a malicious configuration and then swapping it for a restricted, high-privilege mapper type (such as one that hardcodes administrative roles). This allows the attacker to gain full administrative access to the Keycloak realm.
|
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-10-04 | ||
A policy bypass vulnerability exists in Keycloak's Dynamic Client Registration (DCR) "Allowed Protocol Mapper Types" policy. The root cause is located in the testMappers() method of ProtocolMappersClientRegistrationPolicy.java. When a client is updated, the policy checks if the protocol mapper type is in the allow-list. If it is not, the code attempts to verify if the mapper already exists. However, it only validates that the config map of the incoming mapper matches the config of the existing persisted mapper; it fails to verify that the protocolMapper type itself has not changed. An attacker can exploit this by: Registering a client with an allowed mapper type (e.g., oidc-usermodel-attribute-mapper) but providing a configuration intended for a restricted mapper (e.g., {"role": "realm-management.realm-admin"}). Performing a DCR PUT update that keeps the configuration identical but changes the protocolMapper type to a disallowed one, such as oidc-hardcoded-role-mapper. Because the configuration is identical, the policy bypasses the type check. Once persisted, the oidc-hardcoded-role-mapper uses the "role" configuration to inject the realm-admin role into the client's tokens, escalating the attacker to a full realm administrator.