Se un visitatore può mettere sulla sua pagina un testo che altri visitatori vedranno, e quel testo non viene messo in sicurezza, può metterci invece uno script. Quello gira come il suo sito, con la sessione del suo visitatore, e può fare tutto ciò che quel visitatore può fare.

Da dove arriva

  • Un commento, un nome, una recensione: tutto ciò che una persona digita e a un'altra viene mostrato.
  • Un parametro dell'URL ristampato sulla pagina, cioè la casella di ricerca di quasi ogni sito.
  • Il nome di un file caricato.
  • Dati provenienti da un'API che lei non controlla.

L'abitudine

Metta in sicurezza in USCITA, ogni volta, nel contesto in cui sta stampando. Non in ingresso: lo stesso dato può finire dentro l'HTML, dentro un attributo e dentro il JavaScript, e ciascuno vuole un trattamento diverso.

echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
  • Nel testo HTML - htmlspecialchars con ENT_QUOTES.
  • Dentro un attributo - lo stesso, e metta sempre l'attributo fra virgolette.
  • Dentro il JavaScript - json_encode, mai concatenando stringhe.
  • Dentro un URL - urlencode.
Mettere in sicurezza quando il dato viene SALVATO è l'errore classico: lo stesso valore va poi riportato indietro per una mail, un'esportazione o un'API, e una di quelle strade se ne dimentica sempre. Conservi ciò che è stato digitato; lo metta in sicurezza quando viene mostrato.

Un secondo strato

add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;

La CSP dice al browser di eseguire script solo dalla sua stessa origine, così uno script inserito nella pagina non viene eseguito nemmeno se qualcuno passa. La introduca prima in sola segnalazione, altrimenti romperà la sua stessa pagina.

Lo verifichi

Metta un segno innocuo in ogni campo e guardi il SORGENTE della pagina che lo mostra. Vedere il suo segno come testo è giusto; vederlo come un tag è il difetto.

Un motore di template che mette in sicurezza per impostazione predefinita elimina gran parte di questa famiglia di difetti. Se il suo lo fa, non allunghi la mano sull'aiuto per «stampare grezzo» senza una ragione difendibile.