
Joomla 6.1.3 - 高 - リモート - ACL - POST /api/v1/content/articles がカテゴリ単位の ACL を無視する
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · joomla-articles-catid
解説記事: https://abraxaslabs.tech/research/joomla-articles-catid
分類: 権限の残存 到達範囲: リモート
Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters
管理者用の ArticleController::allowAdd は com_content.category.{catid} をチェックします。api/components/com_content/src/Controller/ArticlesController.php には allowAdd がありません。続いて ApiController::add() がデータなしで allowAdd() を呼び出すため、JSON の catid はチェックに一切渡りません。基底の allowAdd は、ユーザーがいずれかのカテゴリで作成可能であれば true になります。
core.login.api と 1 つのカテゴリでの作成権限を付与された Manager クラスの API ユーザーは、UI では拒否されているカテゴリに記事を POST できます。
| ID | CVE 未割当 |
| 分類 | 権限の残存 / 認可バイパス |
| 到達範囲 | リモート (core.login.api を持つ API トークン) |
| CWE | CWE-863 |
| CVSS | Medium: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| 製品 | Joomla CMS |
| 影響を受けるバージョン | 6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2)、POST /api/index.php/v1/content/articles |
| 認証 | Manager (グループ 6) 用の API トークンで、core.login.api、com_content の core.manage、および1 つのカテゴリのみに対する core.create を保有。Super User は不要。デフォルトでは core.login.api は Super User のみ。 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
1 つのカテゴリで作成可能な非 Super User の API トークンを用いて、UI で禁止されているカテゴリに公開できます。この残存権限によって Super User になるわけではありません。これは不正な公開であり、サイトの乗っ取りでも、非表示記事の読み取りでもありません。
| 権限 | メソッド / パス | 種別 | ラボ実証または推測 |
|---|---|---|---|
| 拒否されているカテゴリに記事を作成する | POST /api/index.php/v1/content/articles JSON の catid に B を指定 | 整合性 | ラボ実証済み。HTTP 200、#__content id=1、catid=9(Press)、タイトル poc-art-JOOMLA-ARTICLES-CATID-WITNESS |
| 許可されているのが下書きのみなのに、公開済みコピーを Official notices / Press に設置する | 同じ POST、state=1 | 整合性 | 拒否された Press への作成はラボ実証済み。core.create が拒否されている他のカテゴリアセットについては推測 |
| API 経由で既存記事を編集する | PATCH /api/index.php/v1/content/articles/{id} | n/a | この Manager では閉じていると推測。基底の allowEdit にはコンポーネントの core.edit が必要。ラボの com_content ルールでは core.edit は Author(4)に付与され、Manager(6)には付与されない。ラボでは PATCH を実行していない |
| API 経由で記事を削除する | DELETE /api/index.php/v1/content/articles/{id} | n/a | 閉じていると推測。基底の allowDelete にはコンポーネントの core.delete が必要。ラボでは DELETE を実行していない |
| 管理者画面から許可されたカテゴリ A に記事を保存する | POST ... task=article.save jform[catid]=A | 意図どおり | ラボ実証済みで意図どおりに開いている。HTTP 200、拒否されず |
| 管理者画面から拒否されたカテゴリ B に記事を保存する | 同じタスク、jform[catid]=B | n/a | ラボ実証済みで閉じている。HTTP 200 だが「not permitted」/ create-not-permitted(UI の com_content.category.B に対する allowAdd) |
標準の Manager(core.login.api なし)で API にアクセスする | Bearer トークン / X-Joomla-Token | n/a | 閉じていると推測。デフォルトの core.login.api は Super User(グループ 8)のみ。このラボではまずグループ 6 に付与している |
| contacts / banners / newsfeeds でも同じギャップ | 外部の catid を指定した POST /api/index.php/v1/contacts(および同種のもの) | 整合性 | 推測。これらの API コントローラにも allowAdd がない。ラボでは実行していない |
| Super User / インストーラ RCE | n/a | n/a | 閉じている。Manager は Manager のまま |
2026-07/08 の JSST の一連の報告の後、6.1.3 に固定した。Groups API はすでに core.admin を要求している。Media webservice はすでに override に対する core.edit を要求している。Articles API は依然として ApiController を通過し、「任意のカテゴリへの作成」をすべての catid に対して十分とみなしている。
public function add()
{
if (!$this->allowAdd()) {
throw new NotAllowed('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED', 403);
}
$recordId = $this->save();
$this->displayItem($recordId);
}
Base check:
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'));
}
Administrator UI はすでに 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();
}
誤った方向転換はすでに記録済み:UI の HTTP 200 を許可と読み取ること(B の拒否は「許可されていません」という本文);コンポーネント core.create を穴とみなすこと(ラボの Manager には存在せず、ベースの getAuthorisedCategories カウントには1つのカテゴリ許可で十分);core.login.api を持たない標準の Manager。劇場:リバースシェル。オラクルは Press への API 200、加えて Drafts での UI 許可、Press での UI 拒否である。
同じピンの残り:levels API、menu items API、media override。
python3 joomla-articles-catid-Abraxas-Labs.py
または
cd lab
./run.sh
対象は http://127.0.0.1:19550 のみです。イメージは joomla:6.1.3-php8.3-apache と 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 は次の #__content の自動インクリメント値です(クリーンな 6.1.3 インストールでは 1)。ui-a / ui-b は HTTP 200 を返します。B の拒否は UI の「許可されていません」という本文であり、403 ステータスではありません。
管理者用の ArticleController と同じ方法で、api/components/com_content/src/Controller/ArticlesController.php の allowAdd(および allowEdit)をオーバーライドします。com_content.category.{catid} に対して core.create をチェックします。リクエスト JSON を ApiController::add() に渡すことで、catid が実際にそのチェックに到達するようにします。これらのコントローラがデフォルトの allowAdd のままである場合は、contacts、banners、newsfeeds にも同じパターンを適用してください。
0f2d4de4729eb951e0878fec98c7990da07915b2)ArticlesController.phpApiController.phpGNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。