
Joomla 6.1.3 - High - Remote - ACL - menu items API leftover
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-menu-items-api
Class: Privilege leftover Reach: Remote
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
The administrator UI for menu items checks com_menus.menu.{id} and refuses menutype == main. api/components/com_menus/src/Controller/ItemsController.php has no allowAdd / allowEdit, so ApiController only asks for core.manage plus core.create / core.edit on com_menus.
A token user who may manage one menu can POST /api/index.php/v1/menus/administrator/items onto a menu they are denied in the UI, including the protected administrator main menu.
| ID | no CVE yet |
| Class | Privilege leftover / authorization bypass |
| Reach | Remote (API token with core.login.api) |
| CWE | CWE-863 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Product | Joomla CMS |
| Affected | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2) |
| Auth | Remote API user with core.login.api + core.manage + core.create/core.edit on com_menus, not Super User. Default core.login.api is Super User only. |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 only |
Token user who may create items on menu A only. They still cannot install extensions unless they already have that permission. They do not become Super User from this leftover.
| Privilege | Method / path | Kind | Lab-proven or inferred |
|---|---|---|---|
| Create an item on a menu they are denied | POST /api/index.php/v1/menus/administrator/items with menutype of B | integrity | Lab-proven. HTTP 200, item 102 on staffmenu, title poc-JOOMLA-MENU-ITEMS-API-WITNESS |
Plant a URL on the protected administrator main menu | Same POST with menutype=main | integrity | Lab-proven HTTP 200. UI allowEdit returns false for main |
| Point staff at a lookalike login or hide a real admin item | Published URL item on an admin menu | integrity / recon | Inferred from the write. Lab planted https://example.invalid/ |
| Edit or delete items on menus they do not own | API PATCH / DELETE uses the same missing allow* | integrity | Inferred. Lab exercised create |
| Install extensions or become Super User | Needs other ACL | n/a | Closed. Manager is not Super User |
Closed on this pin: UI add/save on staffmenu for the same user (not permitted). UI add on labmenu still works. Groups API core.admin gate from 6.1.1 is untouched.
I pinned 6.1.3 after the 2026 JSST wave. Administrator ItemController already does the right thing:
return $user->authorise('core.create', 'com_menus.menu.' . $menutypeID);
if ($item->menutype == 'main') {
return false;
}
return $user->authorise('core.edit', 'com_menus.menu.' . (int) $menutypeID);
The API items controller does not override allowAdd / allowEdit. Default ApiController only checks component core.manage plus core.create / core.edit. The model canSave path only checks component core.edit. Batch copy/move already check the menu asset.
Wrong turns already recorded: reading UI HTTP 200 as allow (the body is "not permitted"); treating core.manage on com_menus as enough in the UI (the UI still keys off com_menus.menu.{id}); a stock Manager without core.login.api. Theatre: a reverse shell. The oracle is API 200 on staffmenu and main plus UI denial on B.
Same pin leftovers: levels API, media override, articles catid.
python3 joomla-menu-items-api-Abraxas-Labs.py
or
cd lab
./run.sh
Target only http://127.0.0.1:19530. Image joomla:6.1.3-php8.3-apache.
SUCCESS joomla-menu-items-api api-b-http=200 item-id=102 menutype=staffmenu api-main-http=200 ui-add-b=200 ui-save-b=200 JOOMLA-MENU-ITEMS-API-WITNESS
ui-add-b / ui-save-b are HTTP 200; denial of B is the UI "not permitted" body, not a 403 status.
Copy ItemController::allowAdd / allowEdit (and delete) onto the API controller, including the main block. Check the menu-type asset in canSave the same way.
0f2d4de4729eb951e0878fec98c7990da07915b2)ItemsController.phpItemController.phpGNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.