O que é XSS (cross-site scripting)? 3 tipos e como evitar

O que é XSS (cross-site scripting)? 3 tipos e como evitar

Imagine um campo de comentários num blog. Alguém, em vez de escrever "ótimo post", escreve um trecho de JavaScript. Se o site guarda esse texto e o entrega a cada visitante sem tratar, o navegador de todo mundo que abrir a página vai executar o código, achando que ele faz parte do site. Isso é XSS (cross-site scripting), uma das falhas web mais antigas e mais repetidas — e a que sustenta boa parte do roubo de cookie de sessão.

O que é XSS, afinal?

O que é cross-site scripting (XSS)?

XSS é uma vulnerabilidade em que um site inclui, na página, texto controlado pelo atacante sem tratá-lo, e o navegador da vítima executa esse texto como JavaScript. O código roda com as mesmas permissões do site legítimo.

Segundo a documentação da MDN, como o código roda na origem do site, ele pode acessar o conteúdo da página, o armazenamento local e as credenciais, e fazer requisições em nome do usuário. O ataque exige duas condições: o site aceita uma entrada que o atacante consegue montar, e a coloca na página sem tratamento.

Repare no nome do problema: não é o servidor que é invadido. O alvo é o navegador do visitante, que confia no site e, por tabela, no que o site entrega.

Os 3 tipos de XSS

XSS refletido

O servidor pega um parâmetro da URL e devolve na resposta sem codificar. Exemplo clássico: uma página de busca que mostra "Você buscou: termo". O atacante monta um link com o código no lugar do termo e convence a vítima a clicar — por e-mail, mensagem ou anúncio. É o mesmo roteiro do phishing por e-mail, só que o link aponta para um site legítimo (e vulnerável).

XSS armazenado (persistente)

O código fica salvo no banco de dados — num comentário, perfil, mensagem de suporte — e é servido a todo mundo que abrir a página. A MDN o descreve como particularmente grave, porque não depende de a vítima clicar num link malicioso: basta visitar a página. Painéis administrativos que exibem mensagens de usuários são alvo frequente, já que o "visitante" ali é alguém com muito privilégio.

XSS baseado em DOM

Aqui o servidor nem participa: o próprio JavaScript da página pega um dado (da URL, por exemplo) e o joga no DOM de forma insegura. O padrão típico é usar innerHTML com texto do usuário:

// vulnerável: o que vier em "usuario" vira HTML
bemvindo.innerHTML = `Olá, ${usuario}!`;

// seguro: o que vier em “usuario” vira texto puro bemvindo.textContent = Olá, ${usuario}!;

Se usuario contiver uma tag <img> com um manipulador de evento, a primeira versão executa o código. A segunda mostra o texto literalmente na tela.

O que um atacante consegue fazer com XSS?

  • Roubar a sessão: ler cookies sem a flag HttpOnly e entrar na conta da vítima sem saber a senha.
  • Agir como o usuário: mesmo com o cookie protegido, o script pode enviar requisições autenticadas — trocar e-mail da conta, fazer uma transferência, publicar conteúdo.
  • Exibir formulários falsos dentro do site verdadeiro, para capturar senha ou dados de cartão.
  • Redirecionar a vítima para páginas de golpe ou de download de malware.

É também por isso que 2FA e senha forte não resolvem sozinhos: o código malicioso age depois do login, dentro da sessão já autenticada.

Como evitar XSS (para quem desenvolve ou mantém um site)

A defesa principal é tratar todo dado não confiável no ponto onde ele é escrito na página. O Cheat Sheet de prevenção de XSS da OWASP resume bem: o que importa é a cobertura — um app que protege 99 lugares e esquece um continua vulnerável.

  1. Codificar a saída conforme o contexto. Texto no HTML, valor de atributo, parâmetro de URL e string dentro de script pedem codificações diferentes. Os caracteres <, >, ", ' e & viram entidades HTML no corpo da página.
  2. Usar o escape automático do framework e desconfiar das saídas de emergência: dangerouslySetInnerHTML no React, bypassSecurityTrust* no Angular, unsafeHTML no Lit. O nome já avisa.
  3. Preferir textContent a innerHTML. Se o HTML do usuário for mesmo necessário (editor de texto rico), passe por um sanitizador mantido, como o DOMPurify, que a OWASP recomenda, e não mexa no conteúdo depois.
  4. Colocar aspas nos atributos. Atributo sem aspas deixa o atacante "fechar" o valor e adicionar um evento próprio.
  5. Nunca inserir entrada do usuário dentro de <script> ou <style> — a MDN considera quase sempre inseguro.

CSP e HttpOnly resolvem XSS?

Não. Content Security Policy (CSP) e o cookie HttpOnly reduzem o estrago, mas não corrigem a falha. A OWASP diz explicitamente que a CSP não deve ser a defesa principal.

Uma CSP estrita, com nonce ou hash, faz o navegador recusar scripts injetados e bloqueia manipuladores de evento inline e eval(). A flag HttpOnly impede que o JavaScript leia o cookie de sessão. Os dois valem como camada extra, mas um script injetado ainda consegue agir dentro da sessão. Por fim, o Trusted Types (require-trusted-types-for 'script') obriga os pontos perigosos do DOM a receber valores passados por um sanitizador — não sanitiza sozinho, só garante que a sua função foi chamada, e o suporte entre navegadores ainda é desigual.

E se eu sou só usuário?

Você não corrige o código do site, mas reduz o risco:

  • Desconfie de links de busca ou de login com URL muito longa e cheia de símbolos, vindos de mensagem inesperada.
  • Deslogue de serviços sensíveis (banco, painel administrativo) quando terminar, para encurtar a janela de uma sessão roubada.
  • Mantenha o navegador atualizado e use poucas extensões — uma extensão maliciosa também executa código dentro das suas páginas.
  • Se um site mostrar comportamento estranho (janela de login do nada, redirecionamento), feche a aba e avise o responsável.

A lição maior

XSS e SQL Injection compartilham a mesma raiz: dado e comando misturados no mesmo texto. A OWASP, aliás, agrupa o XSS na categoria Injection no Top 10 de 2021. Mudou o alvo (o banco no SQLi, o navegador no XSS), não a causa. Se você quer ver a mesma ideia aplicada a chatbots, leia Prompt Injection: o que é e por que ameaça chatbots de IA.

Fontes consultadas: MDN Web Docs (Cross-site scripting), OWASP Cross Site Scripting Prevention Cheat Sheet.

Comentários