Vai al contenuto principale
riqo.ioStrumenti per grandi idee

Escaping vs sanitization: contesti HTML e prevenzione XSS

Perché escaping contestuale e sanitization risolvono problemi diversi e come evitare interpretazioni attive di input non affidabile.

Concetto e contesto

Escaping e sanitization sono difese diverse: escaping rappresenta dati in modo che non vengano interpretati come sintassi nel contesto di output, mentre sanitization analizza contenuto strutturato e rimuove o trasforma parti non consentite.

Confonderli produce filtri incompleti e false garanzie.

Per inquadrare correttamente il tema conviene distinguere sempre il concetto astratto dalla sua rappresentazione concreta e dal contesto in cui viene utilizzato. Questa separazione evita di trasferire automaticamente assunzioni valide in un protocollo, una libreria o un formato verso ambienti che possono applicare regole differenti.

Fondamenti e terminologia

Il corretto escaping dipende dal contesto: testo HTML, attributi, URL, CSS e JavaScript hanno grammatiche differenti.

Una sequenza sicura nel testo di un elemento non è automaticamente sicura dentro un attributo evento o una stringa JavaScript.

La terminologia va letta insieme allo standard, alla versione o al contratto che la definisce: parole simili possono indicare proprietà diverse a seconda del livello considerato. Rendere esplicite queste definizioni migliora interoperabilità, documentazione e capacità di diagnosticare risultati inattesi.

Come funziona

I template engine moderni applicano spesso auto-escaping al testo interpolato, ma la protezione può essere bypassata da API che inseriscono HTML raw.

Una sanitizer HTML deve invece comprendere il markup, usare allowlist e gestire URL, attributi e schemi pericolosi.

Nel funzionamento reale è utile seguire il percorso dei dati attraverso i diversi livelli, osservando quali trasformazioni sono reversibili, quali introducono vincoli e dove può andare persa informazione. Questo modello rende più semplice stabilire responsabilità tra producer, consumer, storage e rete.

Esempio ragionato

Mostrare il commento <b>Ciao</b> come testo richiede escaping dei delimitatori HTML; consentire volutamente alcuni tag richiede invece sanitization strutturale.

In quest'ultimo caso una policy può permettere b e em ma rimuovere script, event handler e URL javascript:.

Un esempio è davvero riutilizzabile quando chiarisce non soltanto il risultato finale, ma anche le precondizioni e le proprietà che restano invarianti. Cambiando un'assunzione alla volta si può capire quali parti dell'esempio appartengono allo standard e quali sono invece scelte applicative.

Errori e misconception

Sostituire soltanto < e > non copre tutti i contesti e regex generiche non sono parser HTML affidabili.

Decodifiche multiple, DOM mutation e concatenazione di stringhe tra contesti diversi possono reintrodurre markup attivo dopo un filtro iniziale.

Molti errori nascono da assunzioni implicite tra sistemi che sembrano compatibili ma adottano versioni, canonicalizzazioni o modelli di tipo differenti. Nei casi di interoperabilità o sicurezza conviene quindi trattare gli input anomali come casi da specificare e testare, non come eccezioni trascurabili.

Best practice e criteri di scelta

Mantieni dati non affidabili come testo finché possibile, usa escaping contestuale automatico e ricorri a sanitizer mature solo quando devi accettare HTML.

Aggiungi Content Security Policy come difesa in profondità, ma non considerarla sostituta dell'encoding e della validazione corretti.

Una pratica robusta combina standard documentati, librerie mature, contratti espliciti e test con casi limite rappresentativi. La scelta migliore non è sempre quella più compatta o diffusa: va valutata rispetto a portabilità, leggibilità, prestazioni, sicurezza, evoluzione e costo operativo.

Guide correlate

HTML entities, escaping e sicurezza del markup

Entità HTML, riferimenti numerici, escaping contestuale, sanitization e relazione con la prevenzione XSS.

Bit, byte, nibble, fixed-width integer e complemento a due

Come i calcolatori rappresentano bit e interi signed, e perché larghezza e interpretazione cambiano il valore osservato.