Non inviare mai alcun bit di dati al flusso HTML che non sia stato passato tramite htmlspecialchars()
e hai finito. Regola semplice, facile da seguire, elimina completamente qualsiasi rischio XSS.
Come programmatore è tuo lavoro per farlo, però.
Puoi definire
function h(s) { return htmlspecialchars(s); }
se htmlspecialchars()
è troppo lungo per scrivere 100 volte per file PHP. D'altra parte, usando htmlentities()
non è affatto necessario.
Il punto chiave è:c'è il codice e ci sono i dati. Se mescoli i due, ne derivano cose brutte.
Nel caso dell'HTML, il codice è costituito da elementi, nomi di attributi, entità, commenti. I dati sono tutto il resto. I dati devono essere sfuggito per evitare di essere scambiato per codice.
In caso di URL, il codice è lo schema, il nome host, il percorso, il meccanismo della stringa di query (?
, &
, =
, #
). I dati sono tutto nella stringa di query:nomi e valori dei parametri. Essi devono essere sfuggito per evitare di essere scambiato per codice.
Gli URL incorporati in HTML devono essere doppiamente sottoposto a escape (tramite l'escape dell'URL e HTML-escape) per garantire la corretta separazione di codice e dati.
I browser moderni sono in grado di analizzare il markup incredibilmente rotto e errato in qualcosa di utile. Questa capacità non dovrebbe essere sottolineata, però. Il fatto che qualcosa funzioni (come gli URL in <a href>
senza un corretto escaping HTML applicato) non significa che sia buono o corretto farlo. XSS è un problema che affonda le sue radici in a) persone inconsapevoli della separazione dati/codice (cioè "scappare") o quelle che sono sciatte e b) persone che cercano di essere intelligenti su quale parte dei dati non hanno bisogno di sfuggire.
XSS è abbastanza facile da evitare se ti assicuri di non rientrare nelle categorie a) eb).