Quais são as defesas comuns contra o XSS?

Em outras palavras, quais são as técnicas mais utilizadas para higienizar a input e / ou saída hoje em dia? O que as pessoas em sites industriais (ou mesmo apenas de uso pessoal) usam para combater o problema?

Você deve consultar o excelente site OWASP para obter um resumo dos ataques ( incluindo XSS ) e as defesas contra eles. Aqui está a explicação mais simples que eu poderia encontrar, que pode realmente ser mais legível do que a página da web deles (mas provavelmente nem de longe tão completa).

  1. Especificando um charset. Antes de mais nada, certifique-se de que sua página da web especifique o conjunto de caracteres UTF-8 nos headers ou no início do elemento HTML codifique todas as inputs para impedir um ataque UTF-7 no Internet Explorer (e versões anteriores do Firefox) apesar de outros esforços para impedir o XSS.

  2. HTML em escape. Lembre-se de que você precisa escaping em HTML de todas as inputs do usuário. Isso inclui a substituição de < com < , > com > & com & e " with " . Se você usar atributos HTML com aspas simples, também precisará replace ' por ' . Linguagens de script típicas do lado do servidor , como PHP, fornecem funções para isso, e recomendo que você expandi-los criando funções padrão para inserir elementos HTML em vez de inseri-los de maneira ad-hoc.

  3. Outros tipos de escape. No entanto, você ainda precisa ter cuidado para nunca inserir a input do usuário como um atributo sem aspas ou um atributo interpretado como JavaScript (por exemplo, onload ou onmouseover ). Obviamente, isso também se aplica a elementos de script , a menos que a input seja adequadamente com escape de JavaScript, o que é diferente do escape de HTML. Outro tipo especial de escape é o escape de URL para parâmetros de URL (faça isso antes do HTML escaping para include adequadamente um parâmetro em um link).

  4. Validando URLs e valores de CSS. O mesmo vale para URLs de links e imagens (sem validar com base em prefixos aprovados) por causa do esquema javascript: URL, e também URLs e dados da folha de estilo CSS dentro de atributos de style . (O Internet Explorer permite inserir expressões JavaScript como valores de CSS, e o Firefox é similarmente problemático com seu suporte XBL.) Se você deve include um valor de CSS de uma fonte não confiável, você deve validar com segurança e estritamente ou escaping do CSS.

  5. Não permitindo HTML fornecido pelo usuário. Não permita o HTML fornecido pelo usuário, se você tiver a opção. Essa é uma maneira fácil de acabar com um problema de XSS e, portanto, está escrevendo um "analisador" para sua própria linguagem de marcação baseada em substituições de regex simples. Eu só permitiria texto formatado se a saída HTML fosse gerada de uma maneira obviamente segura por um analisador real que escapa de qualquer texto da input usando as funções de escape padrão e constrói individualmente os elementos HTML. Se você não tiver escolha sobre o assunto, use um validador / desinfetante como o AntiSamy .

  6. Prevenindo o XSS baseado em DOM. Não inclua input do usuário no código HTML gerado por JavaScript e insira-o no documento. Em vez disso, use os methods apropriados do DOM para garantir que ele seja processado como texto, não como HTML.

Obviamente, não posso cobrir todos os casos em que um invasor pode inserir código JavaScript. Em geral, os cookies somente HTTP podem ser usados ​​para tornar um ataque XSS um pouco mais difícil (mas de modo algum evitar um), e dar aos programadores um treinamento de segurança é essencial.

Existem dois tipos de ataque XSS. Uma é onde o seu site permite que o HTML seja injetado de alguma forma. Isso não é tão difícil de defender: ou escape de todos os dados de input do usuário ou retire todas as tags <> e suporte algo como código UBB. Nota: os URLs ainda podem te abrir para ataques do tipo rick-rolling.

A mais insidiosa é quando algum site de terceiros contém uma tag IFRAME, SCRIPT ou IMG ou algo semelhante que atinge uma URL no seu site, e essa URL usará qualquer autenticação que o usuário tenha atualmente em relação ao seu site. Assim, você nunca deve tomar nenhuma ação direta em resposta a uma solicitação GET. Se você receber uma solicitação GET que tente fazer alguma coisa (atualizar um perfil, verificar um carrinho de compras etc.), você deverá responder com um formulário que, por sua vez, exige que um POST seja aceito. Este formulário também deve conter um token de falsificação de solicitação entre sites, para que ninguém possa colocar um formulário em um site de terceiros configurado para enviar ao seu site usando campos ocultos (novamente, para evitar um ataque de mascaramento).

Existem apenas duas áreas principais em seu código que precisam ser tratadas adequadamente para evitar problemas de xss.

  1. antes de usar qualquer valor de input do usuário em consultas, use as funções auxiliares do database como mysql_escape_string sobre os dados e, em seguida, use-as na consulta. Ele irá garantir segurança xss.

  2. antes de exibir os valores de input do usuário de volta nos campos de input do formulário, passe-os por htmlspecialchars ou htmlentities. Isso converterá todos os valores propensos do xss em caracteres que o navegador pode exibir sem ser comprometido.

Depois de ter feito o acima, você está mais do que 95% seguro de ataques xss. Em seguida, você pode aprender técnicas avançadas em sites de segurança e aplicar segurança adicional ao seu site.

O que a maioria dos frameworks faz é desencorajá-lo a escrever diretamente código de formulário HTML ou fazer consultas em forma de string, para que usando as funções auxiliares do framework seu código permaneça limpo, enquanto qualquer problema sério pode ser resolvido rapidamente apenas atualizando uma ou duas linhas de código no framework. Você pode simplesmente escrever uma pequena biblioteca com funções comuns e reutilizá-las em todos os seus projetos.

Se você estiver desenvolvendo no .NET, uma das maneiras mais eficazes de evitar o XSS é usar a Biblioteca do Microsoft AntiXSS . É uma maneira muito eficaz de higienizar sua input.

No JSTL / JSP, a melhor maneira de proteger contra o XSS é usar a tag c: out sem configurar o parâmetro escapeXml padrão igual a false.