Cross-site scripting: quando o navegador da vítima vira a arma

·

·

4 min de leitura

A injeção de SQL ataca o banco de dados do site. O cross-site scripting, o XSS, ataca outra coisa: o navegador de quem usa o site. É uma das falhas mais comuns em aplicação web, e uma das mais mal compreendidas, porque a vítima não é o servidor, é o outro usuário.

Já falei da injeção de SQL em Injeção de SQL. O XSS é primo dela: nasce do mesmo erro de não separar dado de código, só que do lado do navegador.

De onde vem a falha

Um site com XSS aceita um texto de um usuário e o exibe para outros sem tratar. Se esse texto contém código de navegador em vez de texto comum, o navegador de quem vê a página executa esse código, achando que faz parte do site.

O navegador confia no que vem do site. Se o site deixa um usuário injetar código que chega até outro usuário, essa confiança é traída. O código roda com os privilégios do site na sessão da vítima, e é aí que mora o perigo.

Os tipos de XSS

TipoComo funciona
RefletidoO código vai numa requisição e volta na resposta. A vítima precisa clicar num link preparado.
ArmazenadoO código fica salvo no site, num comentário ou perfil, e atinge todo mundo que vê aquela página.
No navegadorA falha está no próprio código que roda no navegador, ao manipular a página de forma insegura.

O armazenado é o mais grave. Um comentário malicioso salvo numa página muito visitada atinge cada visitante, sem precisar enganar ninguém para clicar em nada.

O que um atacante consegue

Executando código no navegador da vítima, dentro da sessão dela no site, o atacante pode:

  • Roubar o cookie de sessão, e com ele assumir a conta da vítima sem saber a senha.
  • Agir em nome da vítima, fazendo o que ela poderia fazer no site.
  • Alterar o que a vítima vê, montando telas falsas para capturar dados.
  • Redirecionar para páginas maliciosas.

O roubo do cookie de sessão é o mais explorado. É por isso que a proteção do cookie, que discuti a propósito de tráfego em claro, importa tanto: o XSS é mais uma via para chegar até ele.

Como testar, com autorização

Em teste autorizado, o primeiro sinal de XSS aparece ao inserir um texto simples e inofensivo com caracteres de marcação em campos que são exibidos de volta, e observar se o navegador o interpreta como código em vez de texto.

# um teste inofensivo: o site exibe isto como TEXTO ou executa?
# se o alerta aparecer, o campo nao trata a entrada = candidato a XSS
<script>alert(1)</script>

A regra do teste é a de sempre: prova sem dano. Confirmar que o navegador executa a entrada e parar. Um alerta simples demonstra a falha sem causar prejuízo, e é suficiente para o relatório.

A correção: tratar a saída

A raiz do XSS é exibir a entrada do usuário sem tratá-la. A correção, portanto, é tratar sempre a saída. Isso se chama codificar a saída: antes de mostrar um texto que veio do usuário, converter os caracteres especiais para que o navegador os exiba como texto, nunca os interprete como código.

Feito isso, o mesmo texto que antes virava código passa a aparecer literalmente na tela, inofensivo. A distinção entre dado e código, que a aplicação vulnerável perdeu, é restaurada no ponto de exibição.

Camadas de apoio

  • Validar a entrada pelo formato esperado, como reforço, nunca como defesa única.
  • Proteger o cookie de sessão para que o código no navegador não consiga lê-lo, o que reduz o impacto mesmo se um XSS passar.
  • Usar uma política que restrinja de onde o navegador pode carregar e executar código na página.

Por que continua comum

Como a injeção de SQL, o XSS é conhecido há anos e a correção é bem estabelecida. E, como ela, continua aparecendo em toda parte, porque cada ponto onde a aplicação exibe algo que veio do usuário é uma oportunidade de esquecer de tratar a saída. Basta um campo esquecido.

Fechar o XSS de verdade não é aplicar uma correção única; é adotar a disciplina de tratar toda saída, em todo ponto, como regra da casa. É trabalhoso e é o que separa a aplicação que resiste da que expõe seus usuários.