Nunca imprima qualquer bit de dados para o fluxo HTML que não tenha sido passado por
htmlspecialchars()
e pronto. Regra simples, fácil de seguir, erradica completamente qualquer risco XSS. Como programador, é seu trabalho para fazê-lo, no entanto.
Você pode definir
function h(s) { return htmlspecialchars(s); }
if
htmlspecialchars()
é muito longo para escrever 100 vezes por arquivo PHP. Por outro lado, usando htmlentities()
não é absolutamente necessário. O ponto-chave é:há código e há dados. Se você misturar os dois, coisas ruins acontecem.
No caso do HTML, código são elementos, nomes de atributos, entidades, comentários. Dados é todo o resto. Dados devem ser escapado para evitar ser confundido com código.
No caso de URLs, o código é o esquema, o nome do host, o caminho, o mecanismo da string de consulta (
?
, &
, =
, #
). Dados são tudo na string de consulta:nomes e valores de parâmetros. Eles devem ser escapado para evitar ser confundido com código. URLs incorporados em HTML devem ser duplamente escapado (por escape de URL e HTML-escaping) para garantir a separação adequada de código e dados.
Os navegadores modernos são capazes de analisar marcações incrivelmente quebradas e incorretas em algo útil. Essa capacidade não deve ser enfatizada, no entanto. O fato de algo acontecer funcionar (como URLs em
<a href>
sem o devido escape de HTML aplicado) não significa que seja bom ou correto fazê-lo. O XSS é um problema que se origina em a) pessoas que não sabem da separação de dados/código (ou seja, "escapando") ou aquelas que são desleixadas eb) pessoas que tentam ser inteligentes sobre qual parte dos dados não precisam escapar. O XSS é bastante fácil de evitar se você se certificar de não se enquadrar nas categorias a) eb).