
CVE-2026-9811 is a Stored Cross-Site Scripting (Stored XSS) vulnerability affecting Mautic 7 (versions 7.0.0 through 7.1.1).
CVE-2026-9811 è una vulnerabilità di Cross-Site Scripting persistente (Stored XSS) che colpisce Mautic 7 (versioni dalla 7.0.0 alla 7.1.1). La vulnerabilità è presente nel componente Project Selector, dove i nomi dei progetti restituiti tramite una richiesta AJAX vengono inseriti nella pagina senza una corretta codifica dell'output o sanificazione. Un utente autenticato con il permesso di creare progetti può memorizzare un payload JavaScript dannoso in un nome di progetto. Quando successivamente un altro amministratore apre un editor di entità contenente il selettore di progetti, lo script dannoso viene eseguito nel suo browser.
Proprietà Valore Prodotto Mautic Versioni interessate 7.0.0 – 7.1.1 Versione corretta 7.1.2 Componente Project Selector Tipo di vulnerabilità Stored Cross-Site Scripting (XSS)
L'applicazione memorizza i nomi dei progetti forniti dagli utenti autenticati e successivamente li recupera tramite un endpoint AJAX. Durante il rendering del selettore di progetti, l'applicazione inserisce questi valori direttamente nel DOM come elementi HTML di tipo option senza eseguire l'escape o la sanificazione del contenuto.
Concettualmente:
User creates project
│
▼
Project name stored in database
│
▼
AJAX returns project name
│
▼
Inserted into DOM without sanitization
│
▼
Browser executes embedded JavaScript
Poiché l'applicazione considera affidabili i dati memorizzati, JavaScript dannoso viene eseguito ogni volta che un altro utente privilegiato carica la pagina vulnerabile.
Attacker
│
▼
Creates a project with a malicious JavaScript payload as its name
│
▼
Payload is stored in the database
│
▼
Administrator opens an entity editor
│
▼
AJAX request retrieves project names
│
▼
Application inserts project name into the DOM without encoding
│
▼
Browser executes the malicious script
│
▼
Attacker gains actions within the administrator's session
Un attaccante con il permesso di creare progetti crea un progetto il cui nome contiene un payload JavaScript dannoso.
Successivamente, un amministratore modifica un'altra entità che include il Project Selector. Il selettore carica i nomi dei progetti tramite AJAX e li inserisce direttamente nella pagina. Poiché il nome del progetto non viene sanificato, il browser esegue lo script incorporato con i privilegi dell'amministratore.
Immagina che Mautic abbia un modulo come questo:
POST /projects/create HTTP/1.1
Content-Type: application/x-www-form-urlencoded
projectName=Marketing Campaign
description=Email Campaign
Il progetto viene salvato come:
Marketing Campaign
Passo 2: L'attaccante crea un progetto
Invece di un nome normale, l'attaccante inserisce HTML contenente un evento JavaScript innocuo:
POST /projects/create HTTP/1.1
Content-Type: application/x-www-form-urlencoded
projectName=<img src="https://raw.githubusercontent.com/aj2108/cve-2026-9811/HEAD/x" onerror="console.log('XSS Demo')">
description=Test
Il database ora memorizza esattamente quella stringa.
Passo 3: AJAX restituisce il valore memorizzato
Successivamente, un amministratore apre una pagina che carica i progetti.
Risposta AJAX:
{
"id": 7,
"projectName": ""
}
Passo 4: JavaScript vulnerabile
Supponiamo che l'applicazione faccia questo:
const project = response.projectName;
document.getElementById("projects").innerHTML +=
`<option>${project}</option>`;
Il browser vede:
<option>
<img src="https://raw.githubusercontent.com/aj2108/cve-2026-9811/HEAD/x" onerror="console.log('XSS Demo')">
</option>
Poiché l'applicazione ha inserito la stringa come HTML anziché come testo, il browser la interpreta come un vero elemento . L'immagine non viene caricata (src="x"), causando l'esecuzione del gestore onerror.
Lo sfruttamento riuscito può consentire a un attaccante di:
| Metrica | Punteggio |
|---|---|
| CVSS v3.1 (CNA) | 5.4 (Medio) |
NVD non ha ancora pubblicato la propria valutazione CVSS per questa CVE.
Nota: Il produttore non ha pubblicato il codice sorgente vulnerabile esatto. Il seguente esempio illustra solo il pattern di vulnerabilità.
// Data returned from AJAX
const project = response.projectName;
// Unsafe: inserted directly into the DOM
document.getElementById("projectSelector").innerHTML +=
`<option>${project}</option>`;
Il nome del progetto ha origine dall'input utente ma viene inserito nella pagina senza codifica HTML. Se il valore memorizzato contiene HTML o JavaScript, il browser lo interpreta come contenuto eseguibile anziché come testo semplice.
const option = document.createElement("option");
// Safe: assign as text, not HTML
option.textContent = response.projectName;
document.getElementById("projectSelector").appendChild(option);
Oppure, se l'output HTML è inevitabile, assicurarsi di applicare una corretta codifica dell'output prima dell'inserimento.
L'uso di textContent (o di un'API sicura equivalente) garantisce che eventuali caratteri speciali vengano trattati come testo semplice anziché come HTML o JavaScript eseguibile. Anche se un nome di progetto dannoso viene memorizzato nel database, verrà visualizzato letteralmente invece di essere eseguito.