
Joomla 6.1.3 - Alta - Remota - ACL - GET /api/v1/users/levels filtra los niveles de vista
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-levels-api
Análisis: https://abraxaslabs.tech/research/joomla-levels-api
Clase: Privilegio residual Alcance: Remoto
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
Usuarios administradores -> Ver niveles de acceso requiere core.admin en com_users (LevelController::allowSave y delete). El webservice de Grupos ya hace lo mismo (GroupsController, 6.1.1). LevelsController no tiene ninguna sobrescritura de allowAdd, allowEdit ni delete, por lo que ApiController deja pasar core.manage junto con core.create.
Un token de API de clase Manager, al que se le concede core.login.api sin core.admin, puede crear niveles de acceso que la interfaz prohíbe.
| ID | aún sin CVE |
| Clase | Privilegio residual / omisión de autorización |
| Alcance | Remoto (token de API con core.login.api) |
| CWE | CWE-863 |
| CVSS | Medio: 6.1 CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N |
| Producto | Joomla CMS |
| Afectado | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2) |
| Autenticación | Token de API para Manager (grupo 6) con core.login.api y manage/create/edit de com_users. Sin core.admin. Por defecto core.login.api es solo para Super User. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Usar un token de API que no es de Super User para cambiar qué grupos ven qué páginas. No se convierten en Super User solo con este residuo. Se trata de control de visibilidad de contenido, no de toma de control del sitio.
| Privilegio | Método / ruta | Tipo | Demostrado en laboratorio o inferido |
|---|---|---|---|
| Crear un nivel de acceso | POST /api/index.php/v1/users/levels JSON title, rules (ids de grupo) | integridad | Demostrado en laboratorio. HTTP 200, #__viewlevels id=7, título poc-level-JOOMLA-LEVELS-API-WITNESS |
| Editar un nivel existente (lista de grupos / título) | PATCH /api/index.php/v1/users/levels/{id} | integridad | Inferido. Mismo controlador, sin allowEdit. En el laboratorio solo se creó. |
| Eliminar un nivel | DELETE /api/index.php/v1/users/levels/{id} | integridad / disponibilidad de filas ACL | Inferido. Misma sobrescritura ausente. En el laboratorio no se ejecutó DELETE. |
| Exponer un artículo, módulo o elemento de menú solo para miembros | Nivel nuevo o parcheado cuyas rules incluyan Public / Guest / Registered | reconocimiento (visibilidad de contenido) | Inferido a partir de #__viewlevels.rules. En el laboratorio se insertó la fila; no se re-ACLó un artículo en vivo. |
| Ocultar una página a Registered, o añadir el grupo del atacante a un nivel Special | Mismo PATCH / create | integridad | Inferido. Mismo almacén. |
| Mutar grupos de usuarios desde la API | POST /api/index.php/v1/users/groups | n/a | Demostrado en laboratorio cerrado. HTTP 403 (GroupsController core.admin) |
| Abrir Usuarios -> Ver niveles de acceso en el administrador | GET /administrator/index.php?option=com_users&view=levels | n/a | Demostrado en laboratorio cerrado. HTTP 403 |
| Guardar un nivel desde la interfaz | POST ... task=level.save | n/a | Demostrado en laboratorio cerrado. HTTP 403 (LevelController::allowSave requiere core.admin) |
Acceder a la API con un Manager estándar (sin core.login.api) | Token Bearer / X-Joomla-Token | n/a | Inferido cerrado. Por defecto core.login.api es solo para Super User (grupo 8). Este laboratorio primero lo concede al grupo 6. |
| RCE de Super User / instalador | n/a | n/a | Cerrado. Manager sigue siendo Manager. |
Fijé joomla/joomla-cms 6.1.3 después de la oleada de JSST de 2026-07/08. La API de Groups ya requiere core.admin. Los niveles de vista todavía pasan por ApiController (core.manage más core.create / core.edit / core.delete). La única lógica adicional en LevelsController es la decodificación JSON de PATCH de rules.
Groups hermano corregido:
public function allowAdd($data = [])
{
return $this->app->getIdentity()->authorise('core.admin', $this->option);
}
Interfaz de usuario del administrador:
protected function allowSave($data, $key = 'id')
{
return $this->app->getIdentity()->authorise('core.admin', $this->option)
&& parent::allowSave($data, $key);
}
Errores de recorrido ya registrados: tratar la API de Groups como aún abierta (devuelve 403); acceder a la API como un Manager estándar sin conceder primero core.login.api (por defecto es solo Super User, misma configuración que CVE-2026-71574 / 72531 / 48904); interpretar el 403 de la UI como la historia completa (lo que queda es la API). Teatro: una reverse shell. El oráculo es API 200 más Groups 403 más UI 403.
Mismos restos de pin: API de elementos de menú, anulación de media, catid de artículos.
python3 joomla-levels-api-Abraxas-Labs.py
o
cd lab
./run.sh
Dirígete solo a http://127.0.0.1:19520. Imagen joomla:6.1.3-php8.3-apache más 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
Copiar core.admin allowAdd / allowEdit / delete de GroupsController a LevelsController. Mantener la restricción de la interfaz de administrador.
0f2d4de4729eb951e0878fec98c7990da07915b2)LevelsController.phpcore.admin (6.1.1) · CVE-2026-71574GNU Affero GPL v3.0. Consulte LICENSE. Solo para laboratorio de bucle invertido. Sin garantía.