O que é uma vulnerabilidade XSS e como um testador não pode perdê-la

Na minha opinião, alguns testadores já ouviram algo como uma vulnerabilidade XSS. Mas poucas pessoas podem simplesmente contar sobre ela em uma entrevista. Ou verifique efetivamente o site para esta vulnerabilidade. Vamos examinar tudo isso com mais detalhes e tentar encontrar nós mesmos uma vulnerabilidade XSS simples na página de demonstração que preparei especialmente para este artigo.



Se você é um guru de testes de segurança e participa uma ou duas vezes de programas de recompensa de grandes empresas de TI, e o número de XSS que encontrou está na casa das dezenas ou mesmo centenas, você pode ignorar este artigo com segurança. Se você é novo no assunto e está apenas começando a se interessar em pesquisar vulnerabilidades - bem-vindo em cat.







Definição



XSS (Cross-Site Scripting) é uma vulnerabilidade bastante comum que pode ser encontrada em muitos aplicativos da web. Sua essência é bastante simples: um invasor consegue injetar código JavaScript na página que não foi fornecida pelos desenvolvedores. Este código será executado toda vez que as vítimas (usuários regulares) visitarem a página do aplicativo onde este código foi adicionado. E então existem vários cenários de desenvolvimento.



Primeiro, um invasor será capaz de obter as credenciais do usuário e fazer login em sua conta.



Em segundo lugar, o invasor pode, despercebido pela vítima, redirecioná-lo para outra página de clone. Esta página pode parecer completamente idêntica àquela que o usuário esperava ver. Mas pertencerá ao intruso. Se o usuário não perceber a substituição e inserir alguns dados sensíveis nesta página, ou seja, dados pessoais, o invasor os terá.



O terceiro ... sim, em geral, muito mais que você possa imaginar. Quase tudo o que o JavaScript pode fazer é disponibilizado para um invasor. A seguir, examinaremos mais de perto um desses exemplos. Por enquanto, vamos tentar discutir com mais detalhes como funciona a vulnerabilidade. E por que um invasor consegue injetar seu código no aplicativo de outra pessoa sem acessar sua fonte.



Um pequeno aviso. Todas as informações abaixo são apresentadas apenas para fins informativos. O testador deve ser capaz de testar seu aplicativo da web quanto a vulnerabilidades. No entanto, é ilegal explorar vulnerabilidades XSS nos recursos de outras pessoas.



Se falarmos sobre a atual legislação russa, quando um pesquisador testa o produto de outra pessoa quanto a vulnerabilidades ou entra na rede de outra pessoa sem o conhecimento e consentimento do proprietário, suas ações podem ser consideradas ilegais.



Mas voltando ao XSS.



Como funciona a vulnerabilidade?



Em primeiro lugar, como exatamente você consegue injetar código JavaScript em uma página que não existia antes? E como você distribui esse código para outros usuários?



Por exemplo, você pode adicionar o código JavaScript a um campo de entrada, o texto do qual é salvo e posteriormente exibido na página para todos os usuários. Pode ser um campo para inserir informações sobre você em uma página de perfil de rede social ou comentários em um fórum.



O invasor insere texto (e para um código malicioso), que é salvo na página. Quando outros usuários visitarem a mesma página, eles farão o download do JavaScript do invasor junto com o texto. No momento do carregamento, este código funcionará. Obviamente, a vulnerabilidade só funcionará se o texto não estiver seguro quando salvo. Falaremos um pouco mais tarde sobre como fazer isso e por que os desenvolvedores às vezes se esquecem disso.



Este é apenas o exemplo mais simples e óbvio de onde uma vulnerabilidade pode ser escondida. A seguir, consideraremos um exemplo mais interessante em uma página de demonstração especialmente preparada.



Até então, vamos em frente.



Por que esses erros são freqüentemente encontrados em projetos da web?



O resultado final é que o navegador não pode distinguir independentemente texto simples de texto que seja código CSS, HTML ou JavaScript. Ele tentará tratar qualquer coisa entre as tags <script> como código JavaScript. Qualquer coisa entre as tags <style> é considerado CSS. E tudo o que parece uma tag é considerado código HTML.



Se um desenvolvedor deseja que algum texto apenas se pareça com código, mas não é (ou seja, não foi processado pelo navegador, mas exibido como está), esse texto deve ser especialmente processado antes de ser entregue ao navegador. Este processamento é denominado “blindagem”.



No processo de escape do texto neste texto, todos os especiais. os caracteres são substituídos por seus "correspondentes", e o navegador já sabe com certeza que se trata apenas de texto. O mais importante é processar o texto que vem do usuário, pois qualquer usuário pode se tornar um intruso e enviar algum código junto com o texto. Infelizmente, às vezes os desenvolvedores esquecem de escapar em certos lugares em um aplicativo da web e o texto é exibido sem qualquer processamento. Pode haver vários motivos para isso.



Por exemplo, o programador nem sempre tem em mente todos os locais onde o texto especificado pelo usuário aparece na página. Além disso, às vezes, diferentes partes do site podem ser criadas em momentos diferentes e / ou por pessoas diferentes. Nesse caso, a probabilidade de erro aumenta.



Outra razão pode ser que a vulnerabilidade não está no código do próprio desenvolvedor, mas no código da biblioteca que ele usa. Normalmente, essas são algumas estruturas prontas para a criação de serviços da web. Nesse caso, o desenvolvedor, é claro, pode nem mesmo suspeitar que, ao conectar esse framework ao projeto, ele automaticamente conecta a ele uma vulnerabilidade já pronta.



Sempre existe esse risco. No entanto, escrever um aplicativo completamente do zero, sem usar nenhuma biblioteca, é longo e caro hoje em dia. Nem toda empresa pode se dar ao luxo de desenvolver esse nível.



Nesse caso, toda esperança é para os testadores.



Por que uma vulnerabilidade XSS é perigosa?



Vamos mais uma vez, com mais detalhes, falar sobre os perigos de uma vulnerabilidade XSS. A vulnerabilidade em si não é perigosa. Torna-se perigoso quando um intruso o encontra e começa a usá-lo para seus próprios fins. A exploração de uma vulnerabilidade é chamada de “vetor de ataque”. No caso do XSS, existem alguns vetores de ataque.



O exemplo mais simples é roubar cookies de autorização de usuários de um aplicativo da web. Na maioria das vezes, o site no qual há autorização distingue o usuário autorizado pelo denominado cookie de sessão. Caso contrário, o usuário não está autorizado. E se for, pelo valor desse cookie o servidor pode distinguir um usuário de outro.



Todos os cookies são armazenados no computador do usuário. Se eu entrar como meu usuário, verei o valor do meu cookie. E eu simplesmente não consigo descobrir o significado de um estranho.



O mesmo vale para o código JavaScript executado no navegador do usuário. Este código JavaScript verá o valor do cookie do usuário em cujo navegador ele é executado e apenas aquele.



Agora, digamos que um invasor tenha sucesso em injetar código JavaScript em uma página de aplicativo da web. Qualquer usuário que agora visitar esta página terá o código JavaScript executado no navegador. Ele lerá o valor do cookie deste usuário (agora a vítima). Resta apenas passar esse valor para o invasor - e o trabalho está feito. Mas como passar o valor, já que o código malicioso é executado no navegador da vítima?



É muito simples. O mesmo código JavaScript pode criar uma solicitação AJAX para o servidor remoto. Por exemplo, para a seguinte URL: www.zloy-site.ru/stolen= { vine_cookie_value }



O domínio do site zloy pertence ao invasor de nosso exemplo. Todas as solicitações que chegam a este domínio são registradas no banco de dados. Observando os parâmetros de URL, o invasor aprende os valores dos cookies da vítima e pode usá-los para entrar em suas contas.



Como discutimos acima, isso não é a única coisa que torna uma vulnerabilidade XSS perigosa. Portanto, por motivos de segurança e para proteger seus usuários, você precisa ser capaz de encontrar e corrigir tais vulnerabilidades em seus projetos.



Onde posso encontrar o XSS? Como lidar com isso? Página de demonstração com exemplo



Em primeiro lugar, vale a pena verificar se há vulnerabilidades de XSS nos locais do site em que um usuário comum tem a oportunidade de influenciar o conteúdo. Se ele puder adicionar algum texto em algum lugar, ele pode tentar adicionar código JavaScript também.



Vejamos isso com um exemplo específico. Eu preparei uma sandbox muito simples onde a vulnerabilidade XSS estava escondida. Eu sugiro tentar encontrá-lo juntos.



Abrindo a sandbox: https://playground.learnqa.ru/demo/xss



Primeiro, vamos ver como a página funciona. É essencialmente um catálogo de livros muito simples que pode ser pesquisado. Se inserirmos “Ray Bradbury” na consulta, veremos todos os livros que estão neste diretório deste autor.







Um usuário atento já percebeu que o texto que inserimos no campo de busca acabou imediatamente na URL. Este momento ainda é útil para nós.



Por enquanto, vamos tentar inserir alguma bobagem na caixa de pesquisa: “fwefewf”.



Veremos que neste caso nada foi encontrado na página. E o texto da solicitação se repetia no texto do erro:







Então, você e eu encontramos o local onde aparece o texto digitado por nós. Portanto, este é um site potencial para uma vulnerabilidade XSS. Vamos tentar inserir o código JavaScript mais popular para verificar se há uma vulnerabilidade.



<script> alert (123) </script>



Se a página estiver vulnerável, após inserir este código, a seguinte janela aparecerá na página:







Isso significa que nosso código JavaScript foi executado e encontramos uma vulnerabilidade XSS.



Assim, entramos no código e vemos o seguinte aviso:







O formulário não permite a busca por este valor, pois o formulário é validado e quer funcionar apenas com letras e números. À primeira vista, parece que o desenvolvedor levou tudo em consideração e protegeu a página de XSS, mas isso não é totalmente verdade.



Lembra, logo acima, notamos que o texto que inserimos no campo de busca é exibido na URL no chamado parâmetro GET? O nome deste parâmetro é “q”, e o valor é o que inserimos no campo de pesquisa. Isso é feito para que você possa copiar o URL junto com essa string de pesquisa e, da próxima vez, abrir a página com os autores certos imediatamente.



Por exemplo, este URL abrirá imediatamente uma página com apenas os livros de Ray Bradbury: playground.learnqa.ru/demo/xss?q=Ray+Bradbury



Ao contrário do formulário, o desenvolvedor não pode fazer a validação de URL - qualquer usuário pode inserir qualquer URL em seu navegador o que quiser, inclusive com qualquer valor do parâmetro GET. A tarefa do desenvolvedor neste caso é não esquecer de levar em consideração todas as opções e escrever o manipulador correto para o valor deste parâmetro GET.



Vamos verificar se nosso desenvolvedor esqueceu de levar tudo em consideração aqui. Vamos tentar substituir o mesmo código JavaScript no parâmetro GET “q”: https://playground.learnqa.ru/demo/xss?q= <script> alert (123) </script>



Depois de clicar neste URL, vemos que uma janela apareceu na página com o valor 123. Mas por quê?



É muito simples. Lembre-se, quando um site não consegue encontrar os livros de que precisa para uma determinada consulta de pesquisa, ele exibe o texto dessa consulta de pesquisa no texto de um erro? Tipo, não encontrei nada para a consulta "blá blá". Em vez desse "blá, blá", agora temos um código JavaScript com um alerta. O desenvolvedor escreveu uma validação para o campo de entrada e decidiu que era assim que protegia o site de JavaScript sendo incluído na consulta de pesquisa. E ele não escapou do texto de erro. Conseguimos ignorar a validação por meio do URL alterando o valor da consulta de pesquisa lá.



Por uma questão de interesse, agora podemos exibir o valor do nosso cookie de sessão, para isso, em vez de <script> alert () </script>, você precisa substituir outro código na URL: <script> alert (document.cookie) </script>



Vou deixar você brincar com isso você mesmo. :)



Tendo encontrado um bug, você deve contatar os desenvolvedores - eles irão consertá-lo.



Existem muitas maneiras de fechar o erro. O texto de escape não é o único. Você também pode impedir que o próprio JavaScript veja alguns cookies. Para isso, o cookie possui um parâmetro especial “apenas http”. Se estiver definido como TRUE, JavaScript não será capaz de descobrir que tal cookie foi definido e não será capaz de lê-lo e transferi-lo para um invasor, mesmo que ele encontre XSS em seu projeto.



Tudo isso é apenas uma lista pequena, longe de ser completa, de manipulações que evitam vulnerabilidades de XSS. Conforme declarado acima, se XSS for detectado durante o teste, é melhor falar com os programadores.



Se você está interessado em saber mais sobre testes de segurança, deseja entender melhor a estrutura da arquitetura cliente-servidor, entender e aprimorar as formas mais eficazes de encontrar vulnerabilidades em uma aplicação web real, venha ao meu curso "Teste de Segurança". Todas as informações que você precisa estão em meu perfil.



Você encontrará apenas uma teoria útil e necessária sem água e um grande número de exemplos práticos e tarefas. Você explorará muitas páginas da web repletas de uma variedade de vulnerabilidades. O trabalho final será um grande estudo de seu projeto de trabalho ou de um dos aplicativos da web de gigantes como Google, Facebook, Twitter e assim por diante.



All Articles