CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-9799

CVE-2026-9799: Authorization Bypass via UMA Permission Ticket Wildcard in Keycloak

Alon Barad
Alon Barad
Software Engineer

Oct 30, 2026·9 min read·1 visit

Executive Summary (TL;DR)

An authorization bypass in Keycloak's UMA policy evaluation engine allows authenticated users with a valid ticket for one typed resource to gain unauthorized access to all other user-owned resources of the same type when the resource server operates in PERMISSIVE enforcement mode.

CVE-2026-9799 is an authorization bypass vulnerability in the User-Managed Access (UMA) subsystem of Keycloak (org.keycloak.authorization). When a resource server is configured with the non-default PERMISSIVE policy enforcement mode, an authenticated user holding a valid UMA permission ticket for a single typed resource can obtain an authorization Requesting Party Token (RPT) granting access to all resources of the same type across the resource server. By submitting an authorization request with the type selector prefix 'resource-type-any:<type>', the attacker bypasses instance-level owner approval checks for unshared peer resources that lack explicit static administrative policies.

Vulnerability Overview

Keycloak provides fine-grained authorization services modeled around OAuth 2.0 and the User-Managed Access (UMA) 2.0 specification. Within the org.keycloak.authorization subsystem, resource servers can delegate access control decisions to Keycloak, allowing both central administrators and individual resource owners to govern access to protected endpoints and data objects. Under UMA workflows, individual users can register and manage their own resources (ownerManagedAccess = true) and dynamically grant access to requesting parties via permission tickets.

CVE-2026-9799 is an authorization bypass vulnerability classified under CWE-639 (Authorization Bypass Through User-Controlled Key) within the DefaultPolicyEvaluator class located in the server-spi-private module. The flaw occurs during the evaluation of permission requests that utilize the resource-type-any:<type> selector prefix. This selector instructs the authorization engine to evaluate permissions across all resources registered under a specific resource type identifier rather than targeting a single resource instance ID.

When a Keycloak resource server is configured with PolicyEnforcementMode.PERMISSIVE, the policy evaluation engine defaults to granting access whenever an evaluated resource has no associated policies that explicitly deny the request. Because user-managed (UMA) resources rely on dynamic per-instance permission tickets rather than static administrative policies, evaluating unshared peer resources through a wildcard type query causes the evaluator to fall through to the permissive default-allow condition.

Consequently, an authenticated user who possesses a legitimate UMA permission grant for a single resource of a given type can issue an authorization request using resource-type-any:<type> and receive a Requesting Party Token (RPT) containing access permissions for every resource of that type on the resource server, bypassing the requirement for resource owner consent.

Root Cause Analysis

In Keycloak's authorization architecture, DefaultPolicyEvaluator.evaluate(...) orchestrates the evaluation of policies attached to a requested ResourcePermission. A resource server can operate in one of three enforcement modes: ENFORCING (the default mode, which denies access unless an explicit policy grants it), PERMISSIVE (which grants access if no matching policy denies it), and DISABLED (which skips policy evaluation entirely).

When resources are created with ownerManagedAccess = true, access governance is intended to be handled dynamically via PermissionTicketRepresentation objects approved by the resource owner. In typical UMA deployments, static administrative policies are not attached directly to individual user-owned resources or to their overarching resource type definitions. Instead, during authorization evaluation, Keycloak retrieves existing granted tickets associated with the requesting user and evaluates them alongside any applicable server-level policies.

The root cause of CVE-2026-9799 lies in how DefaultPolicyEvaluator handles batch evaluations triggered by the resource-type-any:<type> permission syntax when PolicyEnforcementMode.PERMISSIVE is active. When a client submits an authorization request specifying resource-type-any:<type>, Keycloak resolves all resource instances matching <type> and passes each resource as a ResourcePermission into DefaultPolicyEvaluator.evaluate(...).

For the specific resource where the user holds a valid UMA ticket, evaluation succeeds legitimately. However, as the evaluator iterates over peer resources owned by other users where the requester holds no ticket—and where no static policy is attached to the resource or resource type—zero policies are evaluated. Execution then reaches the fallback check at the end of evaluate(...): if (PolicyEnforcementMode.PERMISSIVE.equals(enforcementMode)). Because the evaluator failed to verify whether the target resource was governed by owner-managed access before invoking grantAndComplete(...), it treated the absence of static policies as an implicit approval, appending the unauthorized resource to the resulting RPT.

Code Analysis

The vulnerability resides in server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultPolicyEvaluator.java. Prior to the patch, the evaluate method checked for attached policies across the resource, its scopes, and its resource type. If no policies were evaluated (meaning the internal evaluation counter remained zero), the method checked if the resource server was operating in PERMISSIVE mode and immediately invoked grantAndComplete(...).

Commit bdb4db353a8b6042eac14ec26e1857138234bfd2 resolves this flaw by inspecting the ownerManagedAccess property of the target Resource before allowing the permissive fallback grant to execute, while also removing unused store factory variable declarations.

File: server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/DefaultPolicyEvaluator.java
@@ -44,10 +44,6 @@ public class DefaultPolicyEvaluator implements PolicyEvaluator {
 
     @Override
     public void evaluate(ResourcePermission permission, AuthorizationProvider authorizationProvider, EvaluationContext executionContext, Decision decision, Map<Policy, Map<Object, Decision.Effect>> decisionCache) {
-        StoreFactory storeFactory = authorizationProvider.getStoreFactory();
-        PolicyStore policyStore = storeFactory.getPolicyStore();
-        ResourceStore resourceStore = storeFactory.getResourceStore();
-
         ResourceServer resourceServer = permission.getResourceServer();
         PolicyEnforcementMode enforcementMode = resourceServer.getPolicyEnforcementMode();
 
@@ -79,6 +75,9 @@ public void evaluate(ResourcePermission permission, AuthorizationProvider author
         }
 
         if (PolicyEnforcementMode.PERMISSIVE.equals(enforcementMode)) {
+            if (resource != null && resource.isOwnerManagedAccess()) {
+                return;
+            }
             grantAndComplete(permission, authorizationProvider, executionContext, decision);
         }
     }

The annotated post-patch logic in DefaultPolicyEvaluator.java functions as follows:

// After checking resource, type, and scope policies, if no policies matched:
if (PolicyEnforcementMode.PERMISSIVE.equals(enforcementMode)) {
    // FIX: Prevent owner-managed (UMA) resources from defaulting to 'grant'
    // when no static policies are attached during PERMISSIVE mode evaluation.
    if (resource != null && resource.isOwnerManagedAccess()) {
        return;
    }
    grantAndComplete(permission, authorizationProvider, executionContext, decision);
}

Fix Completeness Assessment

The fix directly addresses the logical inconsistency between PolicyEnforcementMode.PERMISSIVE and UMA resource semantics. By returning early when resource.isOwnerManagedAccess() evaluates to true, the evaluator ensures that user-managed resources always require an explicit positive decision (such as a granted UMA permission ticket or an explicit policy) regardless of whether the resource is queried directly by ID or indirectly through a resource-type-any:<type> wildcard selector. This closes the bypass vector without altering the expected behavior of PERMISSIVE mode for standard, non-UMA server resources.

Exploitation

Exploiting CVE-2026-9799 requires a specific combination of server configuration and initial user state. First, the target Keycloak client (resource server) must be configured with PolicyEnforcementMode.PERMISSIVE. Second, the target resources must share a common type attribute (e.g., patient-data) and have ownerManagedAccess set to true. Third, no explicit static policy can be bound to the resource type itself. Finally, the attacker must be an authenticated user who has obtained at least one valid, owner-approved UMA permission ticket for any single resource of that target type.

Once these prerequisites are satisfied, the attacker sends an OAuth 2.0 token request to Keycloak's token endpoint (/realms/{realm}/protocol/openid-connect/token) using the UMA grant type (urn:ietf:params:oauth:grant-type:uma-ticket). Instead of requesting permissions for the specific resource ID they were granted access to, the attacker supplies the permission parameter formatted as resource-type-any:<type>#<scope>.

The upstream test case added in UserManagedPermissionServiceTest.java demonstrates the exact reproduction sequence:

@Test
public void testResourceTypeAnyDoesNotLeakOwnerManagedResources() {
    // 1. User 'alice' creates an owner-managed resource of type 'patient-data'
    ResourceRepresentation aliceResource = new ResourceRepresentation();
    aliceResource.setName("alice-medical-records");
    aliceResource.setType("patient-data");
    aliceResource.setOwnerManagedAccess(true);
    aliceResource.addScope("read", "write");
    aliceResource = getAuthzClient().protection("alice", "password").resource().create(aliceResource);
 
    // 2. User 'marta' creates an unshared owner-managed resource of the same type
    ResourceRepresentation martaResource = new ResourceRepresentation();
    martaResource.setName("marta-medical-records");
    martaResource.setType("patient-data");
    martaResource.setOwner("marta");
    martaResource.setOwnerManagedAccess(true);
    martaResource.addScope("read", "write");
    martaResource = getAuthzClient().protection("marta", "password").resource().create(martaResource);
 
    // 3. User 'kolo' requests and receives an approved UMA ticket ONLY for Alice's resource
    PermissionResponse ticketResponse = getAuthzClient().protection()
            .permission().create(new PermissionRequest(aliceResource.getId(), "read"));
    AuthorizationRequest koloRequest = new AuthorizationRequest();
    koloRequest.setTicket(ticketResponse.getTicket());
    koloRequest.setSubmitRequest(true);
 
    List<PermissionTicketRepresentation> tickets = getAuthzClient().protection()
            .permission().findByResource(aliceResource.getId());
    PermissionTicketRepresentation aliceTicket = tickets.get(0);
    aliceTicket.setGranted(true);
    getAuthzClient().protection().permission().update(aliceTicket);
 
    // 4. Resource server operates in PERMISSIVE enforcement mode
    ResourceServerRepresentation settings = authzAdmin.getSettings();
    settings.setPolicyEnforcementMode(PolicyEnforcementMode.PERMISSIVE);
    authzAdmin.update(settings);
 
    // 5. 'kolo' requests an RPT using the 'resource-type-any:patient-data' selector
    AuthorizationRequest request = new AuthorizationRequest();
    request.addPermission("resource-type-any:patient-data", "read");
 
    AuthorizationResponse response = getAuthzClient().authorization("kolo", "password").authorize(request);
    AccessToken rpt = toAccessToken(response.getToken());
    Collection<Permission> permissions = rpt.getAuthorization().getPermissions();
 
    // On vulnerable versions, 'permissions' contains both 'alice-medical-records' and 'marta-medical-records'.
    // On patched versions, 'permissions' contains only 'alice-medical-records' (size == 1).
}

When executed against an unpatched Keycloak instance, the returned Requesting Party Token (RPT) includes signed permission claims for both alice-medical-records and marta-medical-records. The attacker can then present this RPT to the downstream resource server to read or modify Marta's protected resources depending on the requested scopes.

Impact Assessment

The primary impact of CVE-2026-9799 is unauthorized cross-user access to protected resources managed within a single Keycloak resource server. An attacker who satisfies the prerequisites can read and potentially modify confidential data owned by other users of the same application, depending on the scopes defined on the resource type (such as read or write).

The vulnerability is assigned a CVSS v3.1 score of 4.6 (Medium) with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N. The Attack Vector is Network (AV:N) and Attack Complexity is Low (AC:L), as invoking the token endpoint with the resource-type-any: syntax requires no special timing or race conditions once the server configuration is in place. Privileges Required is Low (PR:L) because the attacker must be an authenticated user, and User Interaction is Required (UI:R) because a legitimate resource owner must first approve an initial UMA permission ticket for at least one resource of the target type.

Confidentiality and Integrity impacts are both rated Low (C:L/I:L) with Availability rated None (A:N). The overall scope remains Unchanged (S:U), and the impact is bounded by the non-default configuration requirement (PolicyEnforcementMode.PERMISSIVE). Deployments using Keycloak's default ENFORCING policy enforcement mode are not affected by this flaw.

According to Exploit Prediction Scoring System (EPSS) metrics, CVE-2026-9799 has an EPSS score of 0.00294 (0.29%), placing it in the 21.98th percentile. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, and there is no evidence of active exploitation in the wild.

Remediation & Mitigation

To remediate CVE-2026-9799, administrators should upgrade Keycloak to a release containing commit bdb4db353a8b6042eac14ec26e1857138234bfd2. For upstream Keycloak deployments, upgrade to version 26.6.4 or 26.4.13 (or later). For Red Hat build of Keycloak environments, apply the corresponding security errata to upgrade the 26.4 branch to 26.4.13-1 (26.4-19) and the 26.6 branch to 26.6.4-2 (26.6-8).

> [!NOTE] > Deployments that have not altered the default ENFORCING policy enforcement mode on their resource servers are not vulnerable to this issue.

For environments where an immediate version upgrade cannot be performed, two configuration workarounds are available to eliminate the exposure:

  1. Switch Policy Enforcement Mode to ENFORCING: In the Keycloak Administration Console, navigate to Clients -> select the target Client / Resource Server -> Authorization -> Settings, and change Policy Enforcement Mode from PERMISSIVE to ENFORCING. Before applying this change in production, verify that all non-UMA resources on the client have appropriate explicit authorization policies attached so legitimate traffic is not disrupted.
  2. Attach an Explicit Policy to the Resource Type: If PERMISSIVE mode is strictly required by the application architecture, create an explicit administrative policy governing the resource type (for example, a default-deny or owner-check policy attached directly to the <type> definition). When a static policy is attached to the resource type, DefaultPolicyEvaluator evaluates that policy instead of falling through to the unguarded PERMISSIVE grant condition.

Official Patches

KeycloakUpstream GitHub commit fixing CVE-2026-9799 in DefaultPolicyEvaluator.java
Red HatRed Hat Security Advisory RHSA-2026:30049
Red HatRed Hat Security Advisory RHSA-2026:30050
Red HatRed Hat Security Advisory RHSA-2026:30083
Red HatRed Hat Security Advisory RHSA-2026:30084

Fix Analysis (1)

Technical Appendix

CVSS Score
4.6/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N
EPSS Probability
0.29%
Top 78% most exploited

Affected Systems

KeycloakRed Hat build of Keycloak 26.4Red Hat build of Keycloak 26.6

Affected Versions Detail

Product
Affected Versions
Fixed Version
Keycloak
Keycloak
< 26.4.1326.4.13
Keycloak
Keycloak
>= 26.6, < 26.6.426.6.4
Red Hat build of Keycloak
Red Hat
>= 26.4, < 26.4.1326.4.13-1
Red Hat build of Keycloak
Red Hat
>= 26.6, < 26.6.426.6.4-2
AttributeDetail
CWE IDCWE-639: Authorization Bypass Through User-Controlled Key
CVSS v3.1 Score4.6 Medium (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N)
Affected Componentorg.keycloak.authorization.policy.evaluation.DefaultPolicyEvaluator
Attack VectorNetwork (OAuth 2.0 / UMA Token Endpoint)
Prerequisite ConfigurationPolicyEnforcementMode.PERMISSIVE with ownerManagedAccess=true
EPSS Score0.29% (21.98th Percentile)
Exploit StatusProof of Concept (Upstream Arquillian Integration Test)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
T1556Modify Authentication Process
Privilege Escalation
CWE-639
Authorization Bypass Through User-Controlled Key

The system's authorization mechanism relies on a user-controlled key or parameter to select an entity, but fails to adequately verify that the requester is authorized to access that entity.

Vulnerability Timeline

Vulnerability reported and filed in Red Hat Bugzilla (Bug ID: 2482471).
2026-05-28
Upstream remediation commit bdb4db353a8b6042eac14ec26e1857138234bfd2 authored and merged by Pedro Igor.
2026-06-09
CVE-2026-9799 published on CVE.org by Red Hat CNA and ingested into the National Vulnerability Database (NVD).
2026-06-25
Keycloak version bumped to 26.6.4 containing the fix.
2026-06-26
NVD record updated with final CVSS v3.1 scoring and CPE configurations.
2026-07-01

References & Sources

  • [1]Red Hat CVE Portal: CVE-2026-9799
  • [2]Red Hat Bugzilla Bug 2482471
  • [3]Keycloak Remediation Commit bdb4db353a8b6042eac14ec26e1857138234bfd2
  • [4]Red Hat Security Advisory RHSA-2026:30049
  • [5]Red Hat Security Advisory RHSA-2026:30050
  • [6]Red Hat Security Advisory RHSA-2026:30083
  • [7]Red Hat Security Advisory RHSA-2026:30084
  • [8]CVE.org Record: CVE-2026-9799

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-9083
4.9

CVE-2026-9083: Arbitrary Filesystem Path Probing in Keycloak Java Keystore Key Provider

CVE-2026-9083 is a path traversal and information disclosure vulnerability (CWE-22) affecting Keycloak and the Red Hat build of Keycloak. The vulnerability resides in the Java Keystore key provider component (JavaKeystoreKeyProviderFactory), which fails to restrict the user-supplied keystore file path to a designated directory. An authenticated realm administrator holding the 'manage-realm' role can supply arbitrary absolute or relative filesystem paths when configuring a key provider. Because the application returns distinct error messages depending on whether the target path does not exist, lacks read permissions, or fails keystore parsing, an attacker can use this component as an oracle to probe the underlying host filesystem.

Alon Barad
Alon Barad
4 views•11 min read
•about 3 hours ago•CVE-2026-9086
7.3

CVE-2026-9086: Stored Cross-Site Scripting via Case-Sensitive URI Scheme Validation Bypass in Keycloak

CVE-2026-9086 is a stored Cross-Site Scripting (XSS) vulnerability in Keycloak and the Red Hat build of Keycloak. The vulnerability stems from a case-sensitive URI scheme validation check in DefaultClientValidationProvider, allowing attackers with client registration or management permissions to inject javascript: or data: URIs using mixed-case characters.

Amit Schendel
Amit Schendel
5 views•10 min read
•about 4 hours ago•CVE-2026-62290
7.3

CVE-2026-62290: ClusterIssuer DNS01 Solver Policy Bypass and Credential Exfiltration in cert-manager

CVE-2026-62290 is an incorrect authorization vulnerability (CWE-863) in cert-manager that allows low-privileged Kubernetes namespace tenants to bypass ClusterIssuer DNS01 solver policies and exfiltrate cluster-scoped DNS credentials. By directly creating standalone ACME Challenge custom resources rather than going through the standard Certificate and Order workflow, an attacker can specify arbitrary solver provider configurations while referencing a privileged ClusterIssuer. The cert-manager ACME challenge controller reconciles these directly instantiated Challenge resources without verifying their parentage or validating the user-supplied solver parameters against the referenced ClusterIssuer's selector policies.

Amit Schendel
Amit Schendel
7 views•9 min read
•about 5 hours ago•CVE-2026-118662
6.9

CVE-2026-118662: Access Control Bypass via Uncanonicalized Query Parameters in Vite Development Server

CVE-2026-118662 (also tracked as GHSA-8g5g-mxqh-grgj) is an improper access control and path canonicalization vulnerability in the Vite frontend build and development tool. In version 6.4.4, the Vite development server fails to strip transform and loader query parameters before evaluating file paths against the `server.fs.deny` configuration directive. When the development server is exposed to a network and sensitive files located within `server.fs.allow` match patterns in `server.fs.deny`, an unauthenticated remote attacker can bypass file access restrictions by appending specific query strings such as `?raw` or `?inline` to HTTP requests. This allows arbitrary retrieval of restricted files, including environment configuration files and private cryptographic keys.

Alon Barad
Alon Barad
8 views•11 min read
•about 6 hours ago•CVE-2026-115909
7.5

CVE-2026-115909: Unbounded Symlink-Target Allocation Causes Process Abort in Rust zip Crate

A vulnerability in the Rust `zip` crate (versions 1.3.0 prior to 9.0.0) allows an attacker to trigger an uncatchable process abort via a crafted ZIP archive. When extracting symbolic link entries on Unix or Windows targets, `ZipArchive::extract` passes the untrusted, attacker-controlled `uncompressed_size` header value directly to `Vec::with_capacity` before reading or validating entry payload data. By supplying a 112-byte archive with a ZIP64 extended information field declaring an excessive uncompressed size, an attacker forces the memory allocator to fail and invoke `handle_alloc_error()`, immediately terminating the entire process with `SIGABRT`.

Alon Barad
Alon Barad
5 views•11 min read
•about 7 hours ago•CVE-2026-115906
6.5

CVE-2026-115906: AES Entry HMAC Authentication Bypass in Rust zip Crate

CVE-2026-115906 is a cryptographic authentication bypass vulnerability in the Rust zip library (zip-rs/zip2) affecting versions from 0.6.0 prior to 9.0.0. In the WinZip AE-x AES decryption reader implementation within src/aes.rs, the HMAC-SHA1-80 authentication tag is only validated when the internal byte counter (data_remaining) decrements to exactly zero. Because this counter is initialized from the unauthenticated compressed_size header field, an attacker can craft a ZIP archive where the entry stream hits premature physical end-of-file (EOF) before data_remaining reaches zero, causing the reader to return Ok(0) and skip HMAC verification entirely.

Alon Barad
Alon Barad
7 views•13 min read