Cross-site scripting (XSS)
Um Web site está vulnerável ao XSS quando um hacker pode injetar scripts no lado do cliente para atacar outros usuários. Há dois tipos de XSS: refletido e persistente. É comum a interpretação equivocada de que o XSS não é nada mais que um incômodo. Em alguns casos de XSS refletido, a ameaça é pequena; entretanto, em muitos casos, deixa os usuários vulneráveis ao comprometimento da conta ou algo pior.
O XSS refletido ocorre quando os dados de solicitação são renderizados sem codificação e sem filtragem na resposta. Com a ajuda da engenharia social, o invasor pode enganar o usuário, fazendo-o visitar uma página que cria uma solicitação desse tipo e permitindo que o invasor execute o JavaScript no contexto do usuário atacado. O que se pode fazer com isso varia de acordo com a natureza do "buraco", mas geralmente o XSS é utilizado para sequestrar sessões, roubar credenciais ou realizar outras ações que, de outra forma, não seriam autorizadas.
Geralmente uma ameaça maior que o tipo refletido, uma vulnerabilidade de XSS é considerada persistente quando o servidor salva os dados da solicitação enviados pelo usuário. Já que os dados mal intencionados persistem dentro do aplicativo, o aspecto de engenharia social do ataque se torna mais simples ou é totalmente eliminado, dependendo da utilização.
O CMA está cheio de vulnerabilidades de XSS; só a busca de usuários tem os tipos refletido e persistente. A utilização do tipo refletido é mostrada aqui:
http://localhost/CMA/insecure/search.php?query=%3Cscript%3Ealert
(document.cookie)%3C/script%3E
Os efeitos do ataque de XSS refletido ficam visíveis imediatamente ao navegar para o link, a não ser que as contramedidas estejam estabelecidas no lado do cliente:
Query: <script>alert(document.cookie)</script>
Recursos contra o XSS podem ser integrados a um navegador, como o Microsoft® Internet Explorer ® 8, ou instalados como um plug-in, como o noXSS para o Firefox. Para os seus fins, os filtros do lado do cliente não devem ser considerados, já que não é possível depender dos usuários para instalá-los e, em muitos casos, eles só protegem contra o tipo refletido. Em alguns casos, a filtragem no lado do cliente é, na verdade, contraproducente, introduzindo vulnerabilidades de universal XSS (UXSS). O Internet Explorer 8 — antes de a Microsoft corrigir a falha — era um exemplo disso.
Para ver o XSS persistente em ação, insira no campo First Name ou Last Name do formulário User Preferences as tags de script mostradas aqui e, em seguida, procure o usuário:
<script>alert(document.cookie)</script>
O JavaScript é executado quando o usuário é mostrado nos resultados da busca.
Impeça os scripts de sites cruzados
Para impedir ataques de XSS, normalmente é necessário aplicar a codificação correta à entrada do usuário na resposta do servidor. No caso do exemplo de XSS refletido da busca de usuários, a aplicação da codificação de entidade HTML deve ser suficiente para impedir ações mal intencionadas. É possível realizar essa etapa com a API de PHP usando a função htmlentities : Query: <?php echo htmlentities($query); ?>.
Agora, o teste do ataque com relação ao código atualizado dá um resultado diferente:
Query: <script>alert(document.cookie)</script>
Agora os caracteres de "menor que" e "maior que" estão codificados como entidades HTML, o que impede que o invasor injete marcação. A vulnerabilidade persistente é corrigida da mesma forma (consulte a Listagem 8) com a função htmlentities .
Listagem 8. Uma modificação no CMA para impedir o XSS persistente
while ($row = mysql_fetch_assoc($result))
{
echo "<li>" . htmlentities($row["FirstName"]) . " " .
htmlentities($row["LastName"]) . "</li>";
}
|
Quando dados enviados pelo usuário forem injetados em um valor de atributo HTML, tome o cuidado de garantir que os delimitadores de cadeia de caractere usados para delimitar o valor sejam retirados ou codificados dentro do valor em si. Do contrário, pode ocorrer injeção de atributo:
<a href='http://www.mywebsite.com/'>My Website</a>
A Listagem 9 mostra como a injeção de atributo pode ocorrer.
Listagem 9. Injeção de atributo possibilitada pela falta de codificação das aspas
<a href='http://www.mywebsite.com/'onmouseover='alert(document.cookie) '>My Website</a> |
Como uma camada a mais de segurança, a habilitação do sinalizador HttpOnly do cabeçalho de resposta Set-Cookie impede que scripts do lado do cliente acessem o cookie protegido. Entretanto, não se pode depender desse recurso, porque alguns navegadores não oferecem suporte total para ele.
A próxima seção trata de outra vulnerabilidade comum que pode ser usada para lançar ataques do lado do cliente contra outros usuários de um sistema.