
Keycloak 26.8.1 Médio 6.6 Autenticação remota autenticada remanescente. Um administrador de help-desk com manage-users pode fixar um composto pré-construído de manage-realm em si mesmo e então ler o documento completo do realm. Requer que esse composto já exista. PoC em loopback.
Uma conta de help-desk que deveria apenas redefinir senhas e criar usuários pode se autopromover. Alguém com a role manage-users do Keycloak encontra um cargo residual no realm (uma role composta que inclui silenciosamente manage-realm), atribui esse cargo à própria conta e então lê o documento completo do realm que lhe havia sido ocultado uma requisição antes. Ele não consegue criar essa role composta. Um administrador real do realm precisa tê-la construído primeiro. Este é o irmão de mapeamento de roles do CVE-2026-94000, que fechou o mesmo truque na entrada em grupos.
Classe: Resíduo de autenticação
Alcance: Remoto (manage-users autenticado)
Keycloak 26.8.1 (24ed1dad) - Red Hat
| ID | ainda sem CVE |
| Classe | Resíduo de autenticação |
| Alcance | Remoto (Admin REST autenticado; requer manage-users mais uma role composta pré-construída) |
| CWE | CWE-269 / CWE-266 |
| CVSS | Médio: 6.6 CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H |
| Produto | Keycloak |
| Afetado | 26.8.1 (24ed1dadf3f246a555adb6d3d4a99e9b3003fb3b); imagem quay.io/keycloak/keycloak:26.8.1 |
| Autenticação | admin delegado com realm-management / manage-users. FGAP v2 é o avaliador padrão. |
| Licença | GNU Affero GPL v3.0 |
| Lab | somente 127.0.0.1:18082 |
Requer uma conta Keycloak existente que já possua manage-users, e uma role de realm ou de cliente cujo próprio nome não seja uma role de admin e cujas roles compostas incluam manage-realm ou realm-admin. Não requer manage-realm no token. Não consegue criar essa role composta. A atribuição direta de uma role chamada manage-realm / realm-admin continua sendo recusada.
| Privilégio | Método / sink | Recon / integridade / disponibilidade | Comprovado em lab ou inferido |
|---|---|---|---|
| Mapear uma role composta não-admin para si mesmo | POST /admin/realms/{realm}/users/{id}/role-mappings/realm com o id e o nome da role composta | Integridade (concessão de role) | Comprovado em lab. HTTP 204. Witness kcr02m7q4 |
| Mesma concessão em uma role de cliente | POST /admin/realms/{realm}/users/{id}/role-mappings/clients/{client} | Integridade | Código-fonte. Mesmo canMapRole em ClientRoleMappingsResource.java:184 |
| Ler o documento completo do realm com o mesmo access token | GET /admin/realms/{realm} após o mapeamento | Recon | Comprovado em lab. Antes: HTTP 200 parcial (sem atributos, sem accessTokenLifespan). Depois: HTTP 200 completo, atributo plantado presente |
Usar manage-realm aninhado em chamadas administrativas posteriores | UserAdapter.hasRole percorre roles compostas; KeycloakIdentity.hasClientRole confia no modelo de usuário | Integridade | Inferido a partir do código-fonte. O oráculo do lab é o GET completo do realm |
realm-admin aninhado quando essa é a role composta | Mesma travessia | Integridade | Inferido. O lab usou manage-realm |
| Controle negativo | Um segundo usuário com manage-users que não mapeia a role composta | n/a | Comprovado em lab. O GET do controle permanece parcial |
Permanece fechado neste resíduo
| Eixo | Método / sink | Por que está fechado |
|---|---|---|
| Integridade | Mapeamento direto de manage-realm / realm-admin / outras AdminRoles.ALL_ROLES | RolePermissionsV2.isRealmAdminRole ainda recusa |
| Integridade | Criar a role composta que inclui uma role de admin | canMapComposite ainda chama checkAdminRoles |
| Integridade | Entrar em um grupo cuja role composta inclui uma role de admin | CVE-2026-94000 percorre roles compostas em GroupUtils.checkAdminGroupRoles |
| Integridade | Criar um usuário já pertencente a esse grupo | Mesma travessia em UsersResource.createUser |
| Recon | Admin REST anônimo | Requer um token manage-users |
| Integridade | RCE no host, realm-admin criando realm-admin | Fora da classe |
GET /admin/realms/{realm} não retorna HTTP 403 para manage-users. Esse papel é, ele próprio, um papel de administrador, pelo que o servidor devolve 200 com um documento parcial. O que sobra são os campos que só aparecem depois de o compósito ser mapeado.
Fixe a versão do Keycloak 26.8.1. As permissões de administração de granularidade fina v2 estão ativas por predefinição. RolePermissionsV2.canMapRole devolve true para todos os papéis que falham isRealmAdminRole e nunca percorre os compósitos. A correção da CVE-2026-94000 percorre-os apenas no caminho dos grupos.
Falsos caminhos já registados: tratar o isRealmAdminRole da v1 como a verificação em vigor (a v2 sobrepõe-se); esperar HTTP 403 no GET do realm antes da concessão (o resultado real é um 200 parcial); voltar a registar a CVE-2026-94000 (junção a grupo, já encerrada); uma reverse shell. Teatro.
python3 keycloak-manage-users-composite-Abraxas-Labs.py
ou:
cd lab
./run.sh
Aponte apenas para http://127.0.0.1:18082. Imagem quay.io/keycloak/keycloak:26.8.1. Docker necessário. O launcher faz chdir para lab/ e executa run.sh.
IOC image=quay.io/keycloak/keycloak:26.8.1 label-version=26.8.1
IOC serverinfo-version=26.8.1
IOC admin-composite=manage-realm
IOC limited-direct=manage-users
IOC control-direct=manage-users
IOC before-status=200 witness=0 full=0
IOC available=sneaky-composite
IOC post-status=204
IOC after-get attempt=1 status=200 witness=1 full=1
IOC control-status=200 witness=0 full=0 same-token=1
SUCCESS KC-H02-ROLEMAP kcr02m7q4
Percorra os compostos em RolePermissionsV2.canMapRole da mesma forma que GroupUtils.checkAdminGroupRoles já faz para a entrada em grupos. Um papel que inclui manage-realm ou realm-admin é um papel de administrador mesmo quando o seu próprio nome não é.
24ed1dadf3f246a555adb6d3d4a99e9b3003fb3b)RolePermissionsV2.canMapRole (RolePermissionsV2.java:59-61)RoleMapperResource.addRealmRoleMappings (RoleMapperResource.java:289-290)GNU Affero GPL v3.0. Consulte LICENSE. Apenas laboratório em loopback. Sem garantia.
Abraxas Labs [email protected]
Por favor, atribua o crédito da CVE à Abraxas Labs.