
Joomla 6.1.3 – Hoch – Remote – ACL – POST /api/v1/content/articles ignoriert ACL pro Kategorie
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-articles-catid
Klasse: Privilegien-Überrest Reichweite: Remote
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
Administrator ArticleController::allowAdd prüft com_content.category.{catid}. api/components/com_content/src/Controller/ArticlesController.php hat kein allowAdd. ApiController::add() ruft dann allowAdd() ohne Daten auf, sodass die JSON-catid nie in die Prüfung gelangt. Das Basis-allowAdd ist wahr, wenn der Benutzer in irgendeiner Kategorie erstellen darf.
Ein API-Benutzer der Manager-Klasse, dem core.login.api und das Erstellen in einer Kategorie gewährt wurde, kann einen Artikel per POST in eine Kategorie einstellen, für die ihm in der UI die Berechtigung verweigert wird.
| ID | noch keine CVE |
| Klasse | Privilegien-Überrest / Autorisierungsumgehung |
| Reichweite | Remote (API-Token mit core.login.api) |
| CWE | CWE-863 |
| CVSS | Mittel: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| Produkt | Joomla CMS |
| Betroffen | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2), POST /api/index.php/v1/content/articles |
| Auth | API-Token für Manager (Gruppe 6) mit core.login.api, com_content core.manage und core.create in nur einer Kategorie. Kein Super User. Standardmäßig ist core.login.api nur für Super User. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Mit einem API-Token eines Nicht-Super-Users, der in einer Kategorie erstellen darf, in Kategorien veröffentlichen, für die er gesperrt ist. Er wird durch diesen Überrest nicht zum Super User. Dies ist unbefugtes Veröffentlichen, keine Übernahme der Website und kein Auslesen verborgener Artikel.
| Privileg | Methode / Pfad | Art | Im Lab nachgewiesen oder abgeleitet |
|---|---|---|---|
| Einen Artikel in einer Kategorie erstellen, für die er gesperrt ist | POST /api/index.php/v1/content/articles JSON-catid von B | Integrität | Im Lab nachgewiesen. HTTP 200, #__content id=1, catid=9 (Press), Titel poc-art-JOOMLA-ARTICLES-CATID-WITNESS |
| Eine veröffentlichte Kopie in Official notices / Press platzieren, obwohl nur Drafts erlaubt sind | Derselbe POST, state=1 | Integrität | Im Lab nachgewiesen: Erstellen in gesperrter Press. Abgeleitet für jedes andere Kategorie-Asset mit verweigertem core.create |
| Einen bestehenden Artikel über die API bearbeiten | PATCH /api/index.php/v1/content/articles/{id} | n/a | Abgeleitet: für diesen Manager geschlossen. Basis-allowEdit benötigt Komponenten-core.edit; die com_content-Regeln im Lab geben core.edit an Author (4), nicht an Manager (6). Im Lab wurde kein PATCH durchgeführt |
| Einen Artikel über die API löschen | DELETE /api/index.php/v1/content/articles/{id} | n/a | Abgeleitet: geschlossen. Basis-allowDelete benötigt Komponenten-core.delete. Im Lab wurde kein DELETE durchgeführt |
| Einen Artikel aus dem Administrator in der erlaubten Kategorie A speichern | POST ... task=article.save jform[catid]=A | beabsichtigt | Im Lab nachgewiesen offen wie beabsichtigt. HTTP 200, nicht verweigert |
| Einen Artikel aus dem Administrator in der gesperrten Kategorie B speichern | Dieselbe Task, jform[catid]=B | n/a | Im Lab nachgewiesen geschlossen. HTTP 200 mit "not permitted" / create-not-permitted (UI-allowAdd auf com_content.category.B) |
Die API mit einem Standard-Manager ansprechen (ohne core.login.api) | Bearer-Token / X-Joomla-Token | n/a | Abgeleitet: geschlossen. Standardmäßig ist core.login.api nur für Super User (Gruppe 8). Dieses Lab gewährt es zuerst Gruppe 6 |
| Dieselbe Lücke bei contacts / banners / newsfeeds | POST /api/index.php/v1/contacts (und Geschwister) mit fremder catid | Integrität | Abgeleitet. Auch diesen API-Controllern fehlt allowAdd. Im Lab wurden sie nicht getestet |
| Super User / Installer RCE | n/a | n/a | Geschlossen. Manager bleibt Manager |
Ich habe 6.1.3 nach der JSST-Welle 2026-07/08 festgenagelt. Die Groups-API erfordert bereits core.admin. Der Media-Webservice erfordert bereits core.edit für Override. Die Articles-API fällt weiterhin durch ApiController und betrachtet "in irgendeiner Kategorie erstellen" als ausreichend für jede catid.
public function add()
{
if (!$this->allowAdd()) {
throw new NotAllowed('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED', 403);
}
$recordId = $this->save();
$this->displayItem($recordId);
}
Basisprüfung:
protected function allowAdd($data = [])
{
$user = $this->app->getIdentity();
if (!$user->authorise('core.manage', $this->option)) {
return false;
}
return $user->authorise('core.create', $this->option)
|| \count($user->getAuthorisedCategories($this->option, 'core.create'));
}
Die Administrator-UI richtet sich bereits nach catid:
protected function allowAdd($data = [])
{
$categoryId = ArrayHelper::getValue(
$data,
'catid',
$this->input->getInt('filter_category_id'),
'int'
);
if ($categoryId) {
return $this->app->getIdentity()->authorise(
'core.create',
'com_content.category.' . $categoryId
);
}
return parent::allowAdd();
}
Bereits dokumentierte Irrwege: UI-HTTP 200 als Erlaubnis lesen (die Verweigerung von B ist der "not permitted"-Body); Komponenten-core.create als die Lücke betrachten (der Lab-Manager hat keine; eine erlaubte Kategorie reicht für den Basis-getAuthorisedCategories-Zähler); ein Standard-Manager ohne core.login.api. Theater: eine Reverse Shell. Das Orakel ist API 200 in Press plus UI-Erlaubnis für Drafts plus UI-Verweigerung für Press.
Überreste desselben Pins: levels API, menu items API, media override.
python3 joomla-articles-catid-Abraxas-Labs.py
oder
cd lab
./run.sh
Ziel nur http://127.0.0.1:19550. Image joomla:6.1.3-php8.3-apache plus mariadb:11.4.
SUCCESS joomla-articles-catid api-http=200 article-id=1 catid=9 cat-a=8 cat-b=9 ui-a=200 ui-b=200 JOOMLA-ARTICLES-CATID-WITNESS
article-id ist der nächste #__content-Autoincrement (1 bei einer sauberen 6.1.3-Installation). ui-a / ui-b sind HTTP 200; die Verweigerung von B ist der UI-"not permitted"-Body, kein 403-Status.