
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
Clase: Privilegio residual Alcance: Remoto
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
Administrator Users -> Viewing Access Levels requiere core.admin sobre com_users (LevelController::allowSave y delete). El webservice de Groups ya hace lo mismo (GroupsController, 6.1.1). LevelsController no tiene override de allowAdd, allowEdit ni delete, por lo que ApiController deja pasar core.manage más 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 de visualización que la UI prohíbe.
| ID | sin CVE todavía |
| Clase | Privilegio residual / bypass 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) |
| Auth | 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 |
| Lab | 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. Esto es control de visibilidad de contenido, no una toma de control del sitio.
| Privilegio | Método / ruta | Tipo | Probado en lab o inferido |
|---|---|---|---|
| Crear un nivel de acceso de visualización | POST /api/index.php/v1/users/levels JSON title, rules (ids de grupo) | integridad | Probado en lab. 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. El lab solo creó. |
| Eliminar un nivel | DELETE /api/index.php/v1/users/levels/{id} | integridad / disponibilidad de filas ACL | Inferido. Mismo override ausente. El lab no hizo 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. El lab insertó la fila; no volvió a aplicar ACL a 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 | Probado en lab cerrado. HTTP 403 (GroupsController core.admin) |
| Abrir Users -> Viewing Access Levels en el administrador | GET /administrator/index.php?option=com_users&view=levels | n/a | Probado en lab cerrado. HTTP 403 |
| Guardar un nivel desde la UI | POST ... task=level.save | n/a | Probado en lab cerrado. HTTP 403 (LevelController::allowSave requiere core.admin) |
Golpear la API con un Manager estándar (sin core.login.api) | Bearer token / X-Joomla-Token | n/a | Inferido cerrado. Por defecto core.login.api es solo para Super User (grupo 8). Este lab 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 tras la oleada de JSST de 2026-07/08. La API de Groups ya requiere core.admin. Los niveles de visualización todavía caen a través de ApiController (core.manage más core.create / core.edit / core.delete). La única lógica extra en LevelsController es la decodificación JSON de rules en PATCH.
Hermano Groups corregido:
public function allowAdd($data = [])
{
return $this->app->getIdentity()->authorise('core.admin', $this->option);
}
UI del administrador:
protected function allowSave($data, $key = 'id')
{
return $this->app->getIdentity()->authorise('core.admin', $this->option)
&& parent::allowSave($data, $key);
}
Caminos equivocados ya registrados: tratar la API de Groups como todavía abierta (da 403); golpear la API como un Manager estándar sin conceder primero core.login.api (por defecto es solo para Super User, misma configuración que CVE-2026-71574 / 72531 / 48904); leer el 403 de la UI como toda la historia (el residuo es la API). Teatro: una reverse shell. El oráculo es API 200 más Groups 403 más UI 403.
Mismos residuos del pin: menu items API, media override, articles catid.
python3 joomla-levels-api-Abraxas-Labs.py
o
cd lab
./run.sh
Objetivo solo 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 allowAdd / allowEdit / delete con core.admin de GroupsController a LevelsController. Mantener la puerta de la UI del administrador.
0f2d4de4729eb951e0878fec98c7990da07915b2)LevelsController.phpcore.admin (6.1.1) · CVE-2026-71574GNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.