Introdução
Você encontra uma vulnerabilidade de XSS armazenado em uma aplicação PHP. Ao analisar os cookies de sessão, percebe que eles estão protegidos pela flag de segurança HTTPOnly, o que significa que não podem ser acessados por scripts em execução no navegador. À primeira vista, essa configuração parece suficiente para neutralizar o impacto de um XSS.
Parece que não há muito a fazer.
Neste artigo, demonstrarei quatro cenários em que é possível realizar explorações com impacto significativo mesmo diante dessa mitigação, apenas encadeando o XSS a outras falhas ou comportamentos inseguros da aplicação.
Mas antes de entrarmos nos cenários, é importante entendermos do que estamos falando.
Conceitos básicos
O que é XSS armazenado?
Cross-Site Scripting (XSS) é uma vulnerabilidade que permite a um atacante injetar código JavaScript malicioso em uma aplicação web. Quando esse código é executado no navegador de outros usuários, o atacante passa a poder executar ações em nome deles na aplicação.
Na variante armazenada (stored XSS), o código injetado permanece persistente no banco de dados da aplicação e é executado automaticamente sempre que qualquer usuário acessa a página afetada. Essa é a forma mais crítica de XSS, pois atinge múltiplas vítimas sem necessidade de interação adicional com o atacante.

O que é a flag HTTPOnly?
A flag HTTPOnly é um atributo de segurança aplicado a cookies. Quando presente, ela impede que o cookie seja acessado por código JavaScript executado na página, restringindo seu uso a requisições HTTP enviadas pelo próprio navegador.
Na prática, isso significa que mesmo que um atacante consiga executar JavaScript na página por meio de um XSS, o comando clássico document.cookie Retornará uma string vazia ou sem o cookie de sessão, impedindo o roubo direto do cookie.

Essa mitigação é amplamente utilizada e, em muitos casos, os desenvolvedores a consideram suficiente para proteger contra o roubo de sessão. Porém, como veremos a seguir, o HTTPOnly resolve apenas o principal vetor de ataque. O XSS continua permitindo a execução arbitrária de código no contexto da aplicação, o que abre diversas portas.
Cenário 1: PHPinfo exposto
Em muitas aplicações PHP, desenvolvedores deixam o arquivo phpinfo.php acessível após a fase de testes, seja por esquecimento, seja por considerá-lo inofensivo. Esse arquivo, no entanto, é uma mina de ouro para um atacante.
Ao acessar a página, o PHP retorna diversas informações sobre o ambiente, incluindo a seção $_COOKIE e HTTP_COOKIE, que exibem todos os cookies enviados pelo navegador do usuário que realizou a requisição. Inclusive os protegidos com HTTPOnly, uma vez que a flag impede apenas o acesso via JavaScript, não o envio automático em requisições.
A técnica de exploração funciona assim: o payload injetado via XSS faz uma requisição em segundo plano para a página phpinfo, usando as credenciais da vítima. O servidor responde com a página renderizada, que inclui os cookies da sessão da vítima em formato de texto plano. O JavaScript do atacante, então, extrai esses cookies do HTML retornado e os envia para um servidor controlado.

Do ponto de vista da vítima, nada acontece. A página infectada carrega normalmente e o ataque ocorre completamente em segundo plano, sem qualquer indicação visual. O atacante, por sua vez, passa a ter em mãos o cookie de sessão e pode assumir a identidade da vítima na aplicação.
A lição aqui é clara: o HTTPOnly protege contra o acesso direto ao cookie via JavaScript, mas não protege contra a capacidade do atacante de executar código autenticado no navegador da vítima.
Cenário 2: proxy reverso
Neste cenário, o atacante utiliza o XSS para redirecionar a vítima para um servidor sob seu controle, configurado como um proxy reverso que aponta para a página de login legítima da aplicação.
O usuário, acreditando que foi deslogado ou simplesmente confiando na aparência da página, insere suas credenciais. O proxy reverso intercepta as credenciais inseridas, repassa-as ao servidor real (que valida o login com sucesso), captura os cookies de sessão retornados e encaminha tudo de volta ao atacante antes de conceder o acesso ao usuário.

O poder desse ataque reside na transparência da experiência. Do lado do usuário, o login parece ter funcionado normalmente. Do lado do atacante, ficam registrados as credenciais digitadas, os cookies de sessão pós-autenticação e, potencialmente, múltiplos acessos se a vítima repetir o comportamento.
Este é um caso clássico em que o HTTPOnly se torna irrelevante: o atacante não precisa roubar o cookie via JavaScript porque ele intercepta o cookie no momento em que ele é emitido pelo servidor.
Cenário 3: Indisponibilidade
O mesmo conceito do Cenário 2 pode ser aplicado de forma mais simples, com um objetivo diferente: inviabilizar o uso de um serviço legítimo.
Nesse caso, o atacante não busca roubar credenciais ou dados. Ele usa o XSS para redirecionar o usuário para qualquer destino externo, inclusive para um link inexistente ou para uma página arbitrária. Toda vez que um usuário acessa a seção afetada, o redirecionamento é executado e ele não consegue utilizar o serviço desejado.
O impacto aqui é a negativa de serviço parcial. A funcionalidade continua existindo no servidor, mas permanece inalcançável aos usuários enquanto o XSS estiver ativo. Dependendo do quão crítica é a seção afetada, isso pode acarretar prejuízo operacional significativo.
Cenário 4: Defacement
No último cenário, o atacante utiliza o XSS para manipular diretamente o DOM da página, alterando conteúdos visíveis, como textos, imagens, logos ou mensagens, para os usuários. Embora o HTTPOnly continue cumprindo seu papel de proteger os cookies, nada impede que o JavaScript injetado modifique a aparência e o comportamento visual da aplicação.
O impacto desse ataque é duplo. Primeiro, há o dano reputacional: quando usuários legítimos encontram conteúdo alterado, ofensivo ou simplesmente incoerente com a identidade da empresa, a percepção de segurança e de profissionalismo da marca é imediatamente afetada. Segundo, há um grau de indisponibilidade: dependendo das alterações realizadas, a seção infectada pode se tornar inutilizável. Botões podem ser escondidos, formulários podem ser sobrescritos, informações críticas podem desaparecer da interface.
Diferentemente dos cenários anteriores, em que o atacante busca proveito direto (credenciais, sessões, dados), o defacement por meio de XSS busca causar dano. É uma modalidade comum em ataques ideológicos, campanhas de intimidação ou demonstrações públicas de falha de segurança.
Reflexão final
O ponto que une todos os cenários apresentados é o mesmo: o HTTPOnly é uma valiosa camada de defesa, mas apenas uma. Ele resolve o vetor mais evidente de exploração de um XSS, o roubo direto de cookies, mas deixa intactas diversas outras possibilidades de impacto, que variam de exfiltração indireta de dados a dano reputacional, passando por roubo de credenciais e negação de serviço.
A lição para desenvolvedores é que mitigações pontuais não substituem uma abordagem de defesa em profundidade. Eliminar o XSS na raiz, por meio de validação adequada de entrada, de encoding correto de saída e de implementação de Content Security Policy, continua sendo o caminho mais seguro.
A lição para os pentesters é que há várias maneiras de explorar vulnerabilidades e impactar um negócio; devemos sempre sair do óbvio e explorar todas as possibilidades. Encontrar a vulnerabilidade é apenas o começo. O impacto real só se revela quando entendemos como as peças se conectam.
Links úteis e referências
- Explicação sobre os diferentes tipos de proxies
- Demonstração de um encadeamento XSS + PHPinfo
- PortSwigger Academy: XSS
CWEs relacionadas
CWE-79: Improper Neutralization of Input During Web Page Generation