
Joomla 6.1.3 - 높음 - 원격 - ACL - POST /api/v1/content/articles가 카테고리별 ACL을 무시함
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · 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입니다.
Manager 등급 API 사용자가 core.login.api와 한 카테고리에 대한 create 권한을 부여받으면, 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 |
| 인증 | core.login.api, com_content core.manage, 그리고 단 하나의 카테고리에 대한 core.create를 가진 Manager(그룹 6)용 API 토큰. Super User 아님. 기본 core.login.api는 Super User 전용. |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
하나의 카테고리에서 생성할 수 있는 비-Super-User API 토큰을 사용하여, 자신이 차단된 카테고리에 게시할 수 있습니다. 이 잔여 권한으로 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 |
| Drafts만 허용된 상태에서 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를 Manager(6)가 아닌 Author(4)에게 부여. 랩에서는 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로 기사 저장 | 동일 task, jform[catid]=B | n/a | 랩 입증 닫혀 있음. HTTP 200과 "not permitted" / create-not-permitted (UI allowAdd가 com_content.category.B에서 동작) |
기본 Manager(no core.login.api)로 API 호출 | Bearer 토큰 / X-Joomla-Token | n/a | 닫혀 있는 것으로 추정. 기본 core.login.api는 Super User(그룹 8) 전용. 이 랩에서는 먼저 그룹 6에 부여함 |
| contacts / banners / newsfeeds에서의 동일한 결함 | POST /api/index.php/v1/contacts (및 형제 엔드포인트)에 외부 catid 지정 | 무결성 | 추정. 해당 API 컨트롤러들도 allowAdd가 없음. 랩에서는 이들을 실행하지 않음 |
| Super User / 설치 프로그램 RCE | n/a | n/a | 닫혀 있음. Manager는 Manager로 남음 |
2026-07/08 JSST 물결 이후 6.1.3을 고정했습니다. Groups API는 이미 core.admin을 요구합니다. Media 웹서비스는 이미 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);
}
기본 검사:
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'));
}
관리자 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의 거부는 "not permitted" 본문임); 컴포넌트 core.create를 결함으로 취급하기 (랩 Manager에는 그것이 없음; 기본 getAuthorisedCategories 카운트에는 한 카테고리 허용이면 충분함); 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의 거부는 403 상태가 아니라 UI의 "not permitted" 본문입니다.
관리자 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 참조. 루프백 랩 전용. 보증 없음.