
Joomla 6.1.3 - Alta - Remota - ACL - GET /api/v1/users/levels vaza níveis de visualização
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-levels-api
Classe: Privilégio remanescente Alcance: Remoto
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
Administrator Users -> Viewing Access Levels exige core.admin em com_users (LevelController::allowSave e delete). O webservice de Groups já faz o mesmo (GroupsController, 6.1.1). LevelsController não possui override de allowAdd, allowEdit ou delete, então o ApiController permite core.manage mais core.create.
Um token de API de classe Manager, concedido core.login.api sem core.admin, pode criar níveis de acesso de visualização que a UI proíbe.
| ID | ainda sem CVE |
| Classe | Privilégio remanescente / bypass de autorização |
| Alcance | Remoto (token de API com core.login.api) |
| CWE | CWE-863 |
| CVSS | Médio: 6.1 CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N |
| Produto | Joomla CMS |
| Afetado | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2) |
| Autenticação | Token de API para Manager (grupo 6) com core.login.api e com_users manage/create/edit. Sem core.admin. O padrão de core.login.api é apenas Super User. |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Usar um token de API que não seja de Super User para alterar quais grupos veem quais páginas. Ele não se torna Super User apenas com esse remanescente. Isso é controle de visibilidade de conteúdo, não tomada de controle do site.
| Privilégio | Método / caminho | Tipo | Comprovado em lab ou inferido |
|---|---|---|---|
| Criar um nível de acesso de visualização | POST /api/index.php/v1/users/levels JSON title, rules (ids de grupo) | integridade | Comprovado em lab. HTTP 200, #__viewlevels id=7, título poc-level-JOOMLA-LEVELS-API-WITNESS |
| Editar um nível existente (lista de grupos / título) | PATCH /api/index.php/v1/users/levels/{id} | integridade | Inferido. Mesmo controller, sem allowEdit. Lab apenas criou. |
| Excluir um nível | DELETE /api/index.php/v1/users/levels/{id} | integridade / disponibilidade de linhas de ACL | Inferido. Mesmo override ausente. Lab não executou DELETE. |
| Expor um artigo, módulo ou item de menu exclusivo para membros | Novo nível ou nível corrigido cujas rules incluam Public / Guest / Registered | recon (visibilidade de conteúdo) | Inferido a partir de #__viewlevels.rules. Lab inseriu a linha; não reaplicou ACL em um artigo ativo. |
| Ocultar uma página de Registered, ou adicionar o grupo do atacante a um nível Special | Mesmo PATCH / create | integridade | Inferido. Mesmo armazenamento. |
| Modificar grupos de usuários pela API | POST /api/index.php/v1/users/groups | n/a | Comprovado em lab fechado. HTTP 403 (GroupsController core.admin) |
| Abrir Users -> Viewing Access Levels no administrador | GET /administrator/index.php?option=com_users&view=levels | n/a | Comprovado em lab fechado. HTTP 403 |
| Salvar um nível pela UI | POST ... task=level.save | n/a | Comprovado em lab fechado. HTTP 403 (LevelController::allowSave exige core.admin) |
Acessar a API com um Manager padrão (sem core.login.api) | Bearer token / X-Joomla-Token | n/a | Inferido fechado. O padrão de core.login.api é apenas Super User (grupo 8). Este lab o concede ao grupo 6 primeiro. |
| RCE via Super User / instalador | n/a | n/a | Fechado. Manager permanece Manager. |
Fixe em joomla/joomla-cms 6.1.3 após a onda JSST de 2026-07/08. A API de Groups já exige core.admin. Os níveis de visualização ainda passam pelo ApiController (core.manage mais core.create / core.edit / core.delete). A única lógica extra em LevelsController é a decodificação JSON de rules no PATCH.
Irmão Groups corrigido:
public function allowAdd($data = [])
{
return $this->app->getIdentity()->authorise('core.admin', $this->option);
}
UI do administrador:
protected function allowSave($data, $key = 'id')
{
return $this->app->getIdentity()->authorise('core.admin', $this->option)
&& parent::allowSave($data, $key);
}
Caminhos errados já registrados: tratar a API de Groups como ainda aberta (ela retorna 403); acessar a API como um Manager padrão sem conceder core.login.api primeiro (o padrão é apenas Super User, mesma configuração de CVE-2026-71574 / 72531 / 48904); ler o 403 da UI como a história completa (o remanescente é a API). Teatro: um reverse shell. O oráculo é API 200 mais Groups 403 mais UI 403.
Remanescentes do mesmo pin: menu items API, media override, articles catid.
python3 joomla-levels-api-Abraxas-Labs.py
ou
cd lab
./run.sh
Alvo apenas http://127.0.0.1:19520. Imagem joomla:6.1.3-php8.3-apache mais mariadb:11.4.
SUCCESS joomla-levels-api api-http=200 level-id=7 groups-api=403 ui-view=403 ui-save=403 JOOMLA-LEVELS-API-WITNESS
Copie core.admin allowAdd / allowEdit / delete do GroupsController para o LevelsController. Mantenha o gate da UI do administrador.
0f2d4de4729eb951e0878fec98c7990da07915b2)LevelsController.phpcore.admin (6.1.1) · CVE-2026-71574GNU Affero GPL v3.0. Veja LICENSE. Apenas lab em loopback. Sem garantia.