Cross-Site Scripting (XSS)

Uma ameaça disfarçada…

Ana Luísa Teixeira
labmm4a
8 min readMar 6, 2022

--

Resumo

Imagina haver uma forma de te fazeres passar por um impostor em sites. Quer dizer… não serias tu exatamente mas sim o que irias lá colocar. E se conseguires enganar a página web, em que o código que cria essa página fosse alterado por ti? Bem, isto é o que acontece com XSS, também conhecido por cross-site scripting. Mas não te deixes levar pela aparente inocuidade deste. Vulnerabilidades de XSS podem ser muito perigosas, especialmente em sites que guardam e utilizam dados dos utilizadores. Isto porque este impostor, quando não é descoberto, permite roubar dados e enganar os utilizadores. Vamos tentar entender mais sobre ele!

Fonte: Apiki

O que é XSS?

Pensando no script (um segmento de código escrito com instruções a serem executadas) de XSS como um impostor, imaginemos também um site como um gabinete. Este gabinete tem uma receção e um BackOffice. O BackOffice é o local onde são guardados vários dados de pessoas que usam os serviços desse gabinete. Além disso, sempre que as pessoas precisam de um destes serviços, dirigem-se ao gabinete onde lhes é fornecido automaticamente o que precisam. Até aqui tudo bem, tudo está seguro e funciona aparentemente bem.

No entanto, há uma porta que dá acesso a tudo o que se encontra neste gabinete. Tendo este uma fechadura, a maior parte das pessoas não consegue entrar lá dentro, apenas usufruir dos serviços que este dá. Esta porta pode ser uma metáfora para os inputs do site, isto é, campos que o utilizador pode inserir dados (barras de pesquisa, inserção de comentários, formulários, etc). Mas o que aconteceria se esta porta tivesse uma fechadura mal feita e pouco protegida? Bastava alguém com conhecimentos para descobrir esta vulnerabilidade e conseguir entrar, podendo manipular o que lá estivesse.

Ora é isto mesmo que o nosso impostor faz para exercer a sua função. Ele traz consigo ferramentas que facilmente usa para abrir a fechadura, entrando depois no gabinete. Aqui consegue mexer em tudo o que existe. Mas o que será que ele vai fazer a seguir?

Tipos de XSS

Já sabemos que o impostor entra no gabinete passando pela porta de entrada. Isto dito de forma mais realista seria a inserção de algum script, com instruções, em campos que permitem a escrita num determinado website.

exemplo de ataque de XSS
exemplo de ataque de XSS

Ora, dentro de todas as alternativas que o impostor tem para se aproveitar do gabinete e dos seus utilizadores, destaco 3 delas.

Não persistente ou refletido

Aqui o ataque não aparece para todas as pessoas. Voltando à nossa analogia, imagina que o impostor está na receção do gabinete, e alguém quer os serviços do mesmo. Este faz-se passar por um responsável do gabinete e o cliente confia nele. Aqui o impostor consegue aproveitar-se do cliente roubando-lhe informação privada que estaria segura se ele realmente fosse o responsável.

Na situação da vida real, existe um script que é inserido a partir de uma vulnerabilidade do website, este script pode ser incluído por exemplo, num link. Quem abrir este link específico, vai ser alvo do ataque. As restantes pessoas que acedem ao site não são afetadas, dado ser uma ataque de XSS não persistente. Também chamado de XSS refletido porque, essencialmente, o que este script faz é aproveitar-se da apresentação dos dados inseridos para apresentar, em vez do conteúdo original que seria executado, outro conteúdo qualquer (podendo mesmo aparecer outra página). Isto tudo manipulado pelo script de XSS que o atacante introduziu nesta instância.

esquema exemplificativo de XSS refletido
esquema exemplificativo de XSS refletido, Fonte: Medium

Estas vulnerabilidades são muitas vezes usadas para phishing, roubando dados de todos os utilizadores que acedam à página e interajam com ela. Aqui está um exemplo que podes consultar de uma vulnerabilidade de XSS encontrada em 2014 no website do Santander Totta.

Persistente ou guardado

Este tipo de ataque não afeta apenas certas pessoas, afeta qualquer pessoa que aceda ao site, ou páginas específicas dentro dele.

O impostor já não está na receção mas sim no BackOffice, a vasculhar a papelada e o que estiver lá dentro. Desta forma, sempre que algum cliente precisar de um serviço do gabinete, vai passar pelo impostor, sendo que o cliente não faz ideia. Isto vai acontecer com todos os clientes que utilizarem os serviços do gabinete.

Isto acontece bastante em websites que tem por exemplo secções de comentários ou reviews que são inseridos por utilizadores e guardados numa base de dados. Se em vez de um comentário for inserido um script malicioso, este vai também ficar guardado. No entanto, a parte que causa maior dano é quando os comentários, incluindo o comentário que contém o script, são mostrados na página e assim executados, para qualquer pessoa que a abra.

esquema exemplificativo de XSS guardado, Fonte: Medium

Um exemplo disto foi um vírus (que no caso era inofensivo, mas poderia não ser) que se propagou pela rede social MySpace em 2005 chamado “Sammy”. Este mostrava a mensagem “but most of all, samy is my hero” no perfil do utilizador. Em 20 horas propagou-se em mais de 1 milhão de utilizadores. Sempre que alguém via esta mensagem no perfil de um utilizador, ficava também infetado pelo vírus.

mensagem no perfil da vítima

Com base no DOM

Antes de mais, o que é isto do DOM? DOM significa Document Object Model e este basicamente define a estrutura na qual o HTML é construído. Também permite ao JavaScript (linguagem de programação normalmente usada nos websites) ir buscar elementos dessa mesma página HTML e manipulá-los.

estrutura em árvore do DOM

Sabendo isto, o que seria o ataque XSS baseado no DOM? Seria também um ataque isolado, como acontece com o XSS refletido, mas a dinâmica é diferente. No caso do XSS refletido, o impostor entra no gabinete, e fica na receção. No caso do XSS baseado no DOM seria como o impostor entrar e ficar na receção mas aqui alterava apenas o mecanismo que existe para fornecer os serviços ao cliente.

Ou seja, aqui o problema não está na alteração direta do código da página web como acontece no XSS refletido, nem na inserção de scripts maliciosos na base de dados como acontece no guardado. Talvez seja um pouco mais difícil de entender…

O script malicioso não entra no código da página (código fonte) mas sim na leitura deste mesmo código, dado a estrutura do DOM não ser inerente à página mas sim usado pelo browser. Ou seja, a leitura deste código é apenas executada e lida pela interface, que é o browser. Por isso é mais difícil detetar este tipo de ataque já que acontece apenas no browser de cada pessoa afetada.

esquema exemplificativo de XSS baseado no DOM, Fonte: Medium

Dados estes 3 exemplos mais conhecidos de ataques de XSS, deves ficar a perguntar-te: mas então como é que isto se resolve? Bem, lembras-te de que o impostor, para entrar no gabinete, tem que passar pela porta, certo? Então isto quer dizer que a segurança da porta era não existente, ou não era forte o suficiente. Quando se coloca uma porta seja em que lugar for, se o quisermos manter seguro, temos de ter em mente que mecanismos de segurança temos que implementar, porque sabemos que qualquer pessoa que passe pode tentar abrir essa porta, ou mesmo quebrar a segurança que esta tem por meios menos convencionais.

Como prevenir ataques de XSS

É isto mesmo que também acontece para websites. Todos os lugares em que os utilizadores podem colocar dados, normalmente campos de preenchimento, têm que estar devidamente protegidos, com a melhor segurança possível para evitar este tipo de ataques. Mas então como se implementam estes mecanismos de segurança e quais são eles?

No caso de portas, seriam fechaduras de alta segurança. No caso de inputs, são condições para o que pode e o que não pode entrar e mecanismos que limpam e analisam o que neles é inserido.

Uma das formas mais comuns é codificar certos caracteres. Fazendo uma pequena explicação, em HTML certos caracteres são usados como forma de identificar conteúdos, isto é chamado de tags. Codificando estes caracteres eles deixam de identificar este tipo de conteúdo especial. Assim o que estiver entre eles não vai ser lido como código a ser executado, vai ser lido apenas como texto normal. Aqui estão estes caracteres bem como a sua codificação:

Um exemplo de script:

Passa a:

Podes experimentar aqui escrever o teu próprio script e ver com este fica codificado!

Existem outras formas de melhorar a segurança, como a utilização de bibliotecas feitas especificamente para isto. Estas têm como objetivo analisar e limpar o código de forma a não permitir ataques de XSS.

Por fim, também é recomendado testar o website para garantir que todos os campos que recebem dados não confiáveis estão devidamente protegidos, para evitar ataques ao website e proteger todos os seus utilizadores.

Links de referência

--

--