Publicado em: 6 de maio de 2005
Por Chris Weber, Casaba Security, LLC (chris@casabasec.com)
Já não se discute se ataques de scripts entre sites são reais e extremamente perigosos. Se você sabe tudo sobre XSS e apenas quer ver algumas idéias sobre teste, vá direto para a seção de testes. Se isto é novidade para você, por favor leia! Ataques de scripts entre sites ocorrem quando uma pessoa mal intencionada, o invasor, pode forçar um usuário inadvertido, a vítima, a executar script de cliente da escolha do invasor. O termo scripts entre sites não é preciso, pois não se trata somente de scripts e não precisa nem ser cross-site. É um nome que foi dado a esta descoberta e ficou. Vamos usar doravante a abreviatura comum XSS.
Invasões XSS envolvem três partes:
| • | O invasor |
| • | A vítima |
| • | O Web site vulnerável que o invasor explora para agir sobre sua vítima |
Dessas três partes, a vítima é a única que realmente executa o código do invasor. O Web site é meramente um veículo para a invasão e não é tipicamente afetado. Uma invasão pode ser feita de várias maneiras. Por exemplo, o invasor envia à vítima, por e-mail, IM, ou outro meio, um URL maliciosamente elaborado. Quando a vítima abre o URL num navegador da Web, o Web site libera a página e o script é executado no computador da vítima.
Com que se parece uma vulnerabilidade XSS?
Como desenvolvedor e testador Web, você sabe que o fundamento tecnológico das aplicações da Web consiste de http e HTML. O protocolo HTTP é o transportador para o HTML, o código usado para fazer o layout da página da Web e formatá-la.
As vulnerabilidades XSS existem quando uma aplicação da Web aceita input do usuário através de solicitações HTTP tais como um GET ou um POST e então re-afixa o input em algum lugar no código de output HTML. Eis o exemplo mais simples:
1. Solicitação Web como esta:
GET http://www.somesite.com/page.asp?pageid=10&lang=en&title=Section%20Title
2. O HTML retornado pelo servidor após fazer esta solicitação inclui:
<h1>Section Title</h1>
Você pode ver que o input do usuário passado ao parâmetro de cadeia de consulta "título" foi provavelmente colocado numa cadeia variável e inserido pela aplicação Web num tag <h1>. Ao fornecer o input o invasor controla o HTML.
3. Agora, se o site não filtra input pelo servidor (pois controles pelo cliente podem ser contornados), um usuário mal intencionado pode abusar disto de várias maneiras:
O invasor pode introduzir código escapando do tag <h1>:
http://www.somesite.com/page.asp?pageid=10&lang=en&title=Section%20Title</h1><script>alert('XSS%20attack')</script>
O output HTML desta última solicitação ficaria assim:
<h1>Section Title</h1><script>alert('XSS attack')</script>
Mesmo com este exemplo dos mais simples, há inúmeras coisas que um invasor poderia fazer com este link. Vamos examinar as ameaças potenciais e seguir para alguns métodos de teste mais avançados.
Até que ponto são sérias as ameaças das invasões XSS?
Com a habilidade de injetar código na página da Web gerada, ameaças potenciais são limitadas apenas pela imaginação. Um invasor pode usar as vulnerabilidades XSS para roubar cookie, para seqüestrar contas, executar ActiveX, executar conteúdo Flash, forçá-lo a fazer download de software e atuar no seu disco rígido e nos seus dados.
Tudo isto pode acontecer simplesmente fazendo você clicar em alguma URL. Quantas vezes por dia você clica numa URL de e-mail recebido de alguém que confia, através de uma sala de bate-papo ou de um site de notícias que você usa?
Invasões "phishing" geralmente exploram as vulnerabilidades XSS para se disfarçarem de sites legítimos. Você já viu muito disso, quando uma mensagem por e-mail de seu banco chega na sua caixa de entrada, informando-o que foram feitas algumas mudanças na sua conta e convidando-o a clicar em algum super hyperlink. Se você examinar mais de perto o URL, ele pode na verdade explorar uma vulnerabilidade no Web site de seu banco, e parecer com algo assim: http://mybank.com/somepage?redirect=<script>alert('XSS')</script>, onde o uso do parâmetro "redirect" foi explorado para efetuar a invasão.
Se você for realmente astuto, você pode atingir o administrador com uma invasão XSS, talvez enviando um e-mail intitulado "Help! This website URL keeps giving me an error!" Depois que o administrador abrir o URL, você pode fazer um grande estrago, como roubar as credenciais dele ou dela.
Tudo bem, entendemos os perigos - invadir os usuários, invadir os administradores, atrair má publicidade para a empresa. Agora vamos examinar mais de perto o ponto central deste artigo - testar seu site em relação a estes problemas.
Teste para vulnerabilidades XSS
Eu fui consultor de segurança em tempo integral por muitos anos e passei por este exercício muitas vezes. Posso resumir um bom plano de teste em duas palavras: seja minucioso. Para você e para mim, encontrar estas vulnerabilidades não se trata de vangloriar direitos sobre o Bugtraq ou o Vulnwatch; trata-se de fazer um bom trabalho. Se isso significa esquadrinhar cada simples parâmetro de cadeia de consulta, valor de cookie, e valor de dados POST na aplicação, quer dizer que vamos ter de trabalhar um pouco mais.
Sem dúvida, uma revisão de segurança completa envolve mais do que simplesmente procurar vulnerabilidades XSS; envolve também modelagem completa de ameaças, teste para overflows, liberação de informações, tratamento de erros, injeção SQL, autenticação e erros de autorização. O lado bom é que fazendo um trabalho minucioso em qualquer das áreas quase sempre se alcança outras. Como, por exemplo, ao testar vulnerabilidades XSS, você vai, com muita freqüência identificar também problemas de tratamento de erros e liberação de informação.
Estou assumindo que você faz parte de uma equipe que desenvolve e testa a aplicação para Web. Nessa posição privilegiada, você pode trabalhar a partir de uma perspectiva mista caixa preta/ caixa branca. Cada uma tem suas vantagens e, juntas podem até apoiar-se mutuamente.
1. | Tenha seu kit de ferramentas em ordem
Assim, eu listei pelo menos três Web proxies aqui. Bem, examine alguns diferentes pois cada um tem seu caráter próprio. O ponto aqui é que você vai precisar interceptar as solicitações HTTP que o seu navegador da Web faz antes que eles sejam enviados, e então modificá-los para injetar seu teste de XSS. Cada uma destas ferramentas vai fazer esse serviço, e algumas também vão lhe mostrar o código fonte do HTML sendo retornado de você escolher interceptar as respostas do servidor. Interceptar as solicitações GET e POST do cliente é extremamente importante. Isto vai lhe permitir contornar qualquer tipo de código de validação de input javascript do lado do cliente que possa ter sido introduzido. Observação para todos os desenvolvedores de Web - controles de segurança do lado do cliente não têm valor. A validação deve sempre ser feita no servidor. | ||||||||
2. | Mapeie o site e seu funcionamento - converse com os desenvolvedores e gerentes | ||||||||
3. | Identifique e liste todos os pontos de entrada de dados por usuários | ||||||||
4. | Pense no todo e liste seus casos para teste
| ||||||||
5. | Comece a testar e preste atenção a saída | ||||||||
6. | Hmmm não é tão fácil, este site é firme. E agora? |
Variando os casos de teste
Nunca é demais repetir: Estudar como os valores de input chegam às páginas de output HTML é extremamente importante. Se eles não estiverem chegando, não perca seu tempo. Se estiverem, examine onde, pois você precisará variar seu teste de acordo. Eu uso algumas variações para identificar parâmetros que aceitam e exibem código scriptável. Existem muitos para listar aqui, mas aqui estão alguns:
1. | >"'><script>alert('XSS')</script> |
2. | >%22%27><img%20src%3d%22javascript:alert(%27XSS%27)%22> |
3. | >"'><img%20src%3D%26%23x6a;%26%23x61;%26%23x76;%26%23x61;%26%23x73;%26%23x63;%26%23x72;%26%23x69;%26%23x70;%26%23x74;%26%23x3a;alert(%26quot;XSS%26quot;)> |
4. | AK%22%20style%3D%22background:url(javascript:alert(%27XSS%27))%22%20OS%22 |
5. | %22%2Balert(%27XSS%27)%2B%22 |
6. | <table background="javascript:alert(([code])"></table> |
7. | <object type=text/html data="javascript:alert(([code]);"></object> |
8. | <body onload="javascript:alert(([code])"></body> |
Há muitas variações para serem tentadas. A chave é entender como o input está sendo processado e entregue na página de output. Como mostram estes exemplos, as variações freqüentemente envolvem preceder o código scriptável com ">"" a fim de tentar fechar tags que o Web site possa produzir n output. Eles envolvem ainda codificação URL do código numa tentativa de contornar filtros de input no lado do servidor. Além disso, uma vez que "<>" são comumente filtrados durante o input, também devem ser testados XSS que não necessitam colchetes, tais como "&{alert('XSS')};"
Persistente vs. dinâmico
Identificar um XSS bem sucedido é difícil, porque a invasão XSS pode não ser tão óbvia a princípio. Como exemplo arbitrário, ao adicionar uma nova mensagem ao site e injetar no valor "msgTitle", você pode não ver o código scriptável executar imediatamente após o dado ser submetido. Todavia, quando você visita o quadro de mensagem, o valor "msgTitle" pode ser usado no HTML da página e executado como código scriptável. A isto se pode referir como uma invasão XSS persistente que ocorre quando o valor contendo o código scriptável seria salvo para o cliente ou ao backend para ser executado depois.
Isto está em contraste com invasões XSS dinâmicas que executam imediatamente e apenas uma vez. Por exemplo, quando um link ou solicitação GTE for formada com código scriptável em um dos valores de cadeia de consulta que controla output na página, então aquele output pode ser exibido somente uma vez quando o link for clicado.
Conclusão
Teste para XSS é geralmente apenas uma pequena parte de uma revisão completa da segurança de uma aplicação da Web, mas justifica que seja feita minuciosamente. Após fazer isso por muitos anos, enfatizo que o uso de uma planilha ou algo mais para documentar todas as páginas no site, juntamente com todos os valores de input que cada página aceita (cadeia de consulta, cookie, POST data, SOAP) é um passo crítico antes mesmo de começar a testar. Igualmente importante é seguir o input e entender como ele é encaminhado na página de output HTML. Se você souber como a aplicação está usando o input, muita coisa será feita muito mais rápido. Não perca tempo tentando input que nunca é exibido como output. Fale com os desenvolvedores e gerentes de projeto e faça um bom trabalho modelando ameaça antes de começar.