self_svg_XSS — Self-XSS → Bot-Assisted ATO via SVG upload
Chain an SVG upload, a `blob:` URL, a chat invite and a headless admin helper bot to turn a Self-XSS into full admin account takeover
$750
Es lo que una empresa pagó por este fallo en HackerOne. Aquí lo tienes reconstruido para que lo encuentres tú.
Aprende a encontrar este bug
Este bug pagó $750 en HackerOne.
Crea tu cuenta y practica bugs reales que se pagaron. Descarga el entorno, encuéntralo y aprende la técnica exacta — tu camino a tu primer bounty.
hunters entrenando
labs de hackeos reales
completaciones
pagados por estos bugs
Acceso a todos los labs · sin permanencia · cancela cuando quieras
Hackers que lo han resuelto· 8
Objetivos
Logro que recibirás
Cuando resuelvas este lab desbloqueas este logro compartible

Writeups de la comunidad
La checklist que repaso en cada objetivo nuevo
47 comprobaciones ordenadas por coste: primero lo que te puede meter en un lío, luego lo barato, y al final lo caro — que es donde están los bounties grandes. Te la mando al correo ahora mismo.
Te das de baja en un clic, desde cualquier correo.
Attack Chain
Root causes (what makes the chain work)
- Unsanitized SVG upload. The server preserves
Content-Type: image/svg+xml
and serves uploads inline (files.ts). - Top-level blob-URL open.
FileAttachment.tsxbuilds a blob URL from the
downloaded file and callswindow.open(blobUrl). A blob URL loaded as a
document inherits the creator's origin, so the SVG's<script>runs inside
NeuroChat's origin. - JWT in
localStorage.auth.tsreturns the token in the JSON response
body and the client stores it inlocalStorage['nc_token']— reachable from
any script running in the origin. - Open chat invites. Any user can invite anyone (including
admin@) into
any chat they own. - Eager admin helper. A headless Chromium bot loads the chat and clicks the
"Open in new tab" button on each attachment, firing the payload.
How to solve
1) Exploration
- Sign in as attacker, upload an SVG that visibly renders (e.g. a simple shape)
- Click Open in new tab — observe it opens on a
blob:URL - Inspect Network tab:
/api/files/:idreturnsContent-Type: image/svg+xml
2) Proof of script exec
Upload an SVG such as:
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="40">
<text y="25">hi</text>
<script>alert(document.domain)</script>
</svg>
Click Open in new tab → alert pops on localhost:1338 → Self-XSS confirmed.
3) Weaponize
Your user id is visible in any decoded JWT (or in /admin if seen, but you are
not admin yet — use atob(token.split('.')[1])). Build an SVG that POSTs your
localStorage to /api/exfil/<id> (see exploit.py).
4) Deliver
Upload the weaponized SVG to a chat. Invite admin@neurochat.ai. The bot polls
every ~15s; it will accept, visit the chat, and click the attachment.
5) Harvest
Open /stolen in the UI (or poll /api/exfil). A capture withemail = admin@neurochat.ai will appear.
6) Takeover
Click Hijack session on that capture (or copy the token intolocalStorage['nc_token']). Browse to /admin → flag.
Or: just run the exploit
python3 exploit.py
Proof of Concept (automated)
exploit.py automates steps 1–6 end-to-end. Typical run:
[1] Login as attacker@neurochat.ai
✓ logged in as #1 (Alex Morgan) · role=user
[2] Create attacker-owned chat
✓ chat id = 5
[3] Craft SVG payload (exfil → /api/exfil/1)
✓ 1.4 KB
[4] Upload dashboard-mockup.svg
✓ mime preserved as image/svg+xml
[5] Post message referencing file
[6] Invite admin@neurochat.ai
[7] Poll /api/exfil for captured admin token
✓ captured admin JWT
[8] Hit /api/admin with stolen JWT
FLAG{e7a15c…}
