O que é CSRF e como evitar requisições forjadas
Entenda como ataques Cross-Site Request Forgery exploram a sessao autenticada do usuario e quais defesas realmente funcionam, de tokens a SameSite.

Você está logado no seu banco em uma aba. Em outra, abre um site qualquer que, sem você perceber, dispara uma requisição para o banco usando a sua sessão ativa. Se o banco aceitar, uma transferência pode acontecer sem que você tenha clicado em nada relevante. Esse é o mecanismo do CSRF (Cross-Site Request Forgery).
Neste artigo você vai entender por que o navegador colabora involuntariamente com esse ataque, em que situações ele funciona e quais defesas são eficazes de verdade. Spoiler: a combinação de tokens anti-CSRF e o atributo de cookie SameSite resolve a esmagadora maioria dos casos.
O que é CSRF
Cross-Site Request Forgery é um ataque em que um site malicioso induz o navegador da vítima a enviar uma requisição autenticada para outra aplicação na qual ela já está logada. O atacante não rouba credenciais nem lê respostas; ele apenas força uma ação aproveitando a sessão existente.
A chave para entender o CSRF é lembrar como os navegadores tratam cookies: por padrão, ao fazer uma requisição para um domínio, o navegador anexa automaticamente os cookies daquele domínio — inclusive o cookie de sessão. O servidor recebe a requisição, vê um cookie válido e assume que é o usuário legítimo agindo. O ataque explora exatamente essa confiança automática. O CSRF figura no contexto de falhas de controle de acesso do OWASP Top 10 explicado: as 10 maiores falhas de segurança web.
O que torna um app vulnerável
Para que um CSRF clássico funcione, três condições precisam estar presentes ao mesmo tempo:
Quebrar qualquer uma dessas três condições neutraliza o ataque. As defesas que veremos atacam justamente os pontos 1 e 3.
Um exemplo concreto
Suponha que uma aplicação faça transferências por uma requisição como esta:
<form action="https://banco.com/transferir" method="POST">
<input name="destino" value="12345">
<input name="valor" value="1000">
</form>Um atacante hospeda uma página com um formulário idêntico que se envia sozinho assim que carrega:
<body onload="document.forms[0].submit()">
<form action="https://banco.com/transferir" method="POST">
<input type="hidden" name="destino" value="conta-do-atacante">
<input type="hidden" name="valor" value="5000">
</form>
</body>Se a vítima, logada no banco, visitar essa página, o navegador envia a requisição com o cookie de sessão anexado. Sem proteção, o banco processa a transferência como legítima. Repare que o atacante nunca viu a senha — ele apenas tomou carona na sessão.
CSRF nem sempre precisa de formulário
Vale entender que o vetor não se limita a formulários. Qualquer elemento que dispare uma requisição serve. Uma simples imagem pode acionar um GET com efeito colateral:
<img src="https://app.com/conta/deletar?id=42" width="0" height="0">Esse exemplo revela um anti-padrão importante: requisições GET jamais devem mudar estado. Operações que alteram dados precisam usar POST, PUT, PATCH ou DELETE, que são mais difíceis de forjar de forma silenciosa. Esse é um dos princípios básicos ao desenhar um O que é HTTP, seus métodos, status e como a web conversa: métodos seguros (como GET) devem ser apenas de leitura.
CSRF não é XSS
É comum confundir os dois, mas eles são diferentes:
Por isso o CSRF afeta principalmente operações que mudam estado (transferir, deletar, alterar e-mail), e não simples leituras. Ainda assim, os dois se relacionam: um XSS pode contornar defesas anti-CSRF, então a proteção contra o forjamento depende também de não ter scripts injetados — assunto de O que é XSS (Cross-Site Scripting)?.
Um ponto importante: se o site tem XSS, nenhuma defesa anti-CSRF segura. Um script injetado roda na origem do alvo, pode ler o token e montar a requisição legítima. Por isso, mitigar XSS é pré-requisito para que a proteção CSRF tenha valor.
Defesa 1: tokens anti-CSRF
A defesa clássica é o token anti-CSRF (também chamado de synchronizer token). A ideia:
<form action="/transferir" method="POST">
<input type="hidden" name="csrf_token" value="a1b2c3d4-e5f6-...">
<!-- demais campos -->
</form>Por que isso funciona? O site malicioso não tem como adivinhar o token, porque não consegue ler o conteúdo das páginas do domínio alvo (a política de mesma origem impede). Sem o token correto, a requisição forjada é rejeitada. O OWASP Web Security Testing Guide detalha como verificar a presença e a robustez desses tokens (OWASP Foundation, 2020).
O padrão Double Submit Cookie
Manter o token associado à sessão no servidor exige guardar estado. Uma alternativa sem estado é o double submit cookie: o servidor envia o token tanto em um cookie quanto espera recebê-lo em um cabeçalho ou campo de formulário. Como o site atacante não consegue ler o cookie do domínio alvo (graças à política de mesma origem), ele não consegue replicar o valor no cabeçalho. O servidor só aceita se os dois baterem.
POST /transferir HTTP/1.1
Cookie: csrf=a1b2c3d4
X-CSRF-Token: a1b2c3d4Esse padrão é popular em APIs e SPAs porque não exige armazenar o token no servidor. Sua robustez, porém, depende de subdomínios confiáveis — por isso costuma-se assinar o token para evitar adulteração.
Cuidados ao implementar tokens
Defesa 2: cookies SameSite
O atributo SameSite instrui o navegador sobre quando enviar um cookie em requisições entre sites. Ele ataca a raiz do problema — o envio automático do cookie de sessão:
Set-Cookie: sessao=abc123; HttpOnly; Secure; SameSite=LaxCom SameSite=Lax ou Strict, o cenário do banco descrito acima já falha, porque o cookie de sessão não acompanha o POST cruzado.
SameSite não é uma bala de prata
Apesar de poderoso, o SameSite tem limitações que justificam não depender só dele:
A recomendação é tratar SameSite como uma camada de defesa robusta, mas combiná-lo com tokens — defesa em profundidade.
Defesa em profundidade: combine as camadas
Nenhuma defesa isolada é perfeita, então o recomendado é somar proteções:
É importante distinguir o que cada peça protege: o token e o SameSite cuidam do forjamento, mas quem o usuário é e o que ele pode fazer depende de um controle de acesso correto — tema de Autenticação vs autorização: qual a diferença?.
Verificação de Origin: simples e eficaz
A checagem do cabeçalho Origin (e, na ausência dele, Referer) é uma defesa subestimada. Em uma requisição que muda estado, o servidor compara a origem declarada com a sua própria:
Origin recebido: https://site-malicioso.com
Origin esperado: https://app.com
=> rejeitarDiferente do cookie, o cabeçalho Origin é controlado pelo navegador e não pode ser forjado por scripts de outro site. É uma checagem barata que reforça as demais.
Casos especiais que enganam
Alguns cenários parecem seguros mas escondem armadilhas de CSRF:
A lição geral: qualquer endpoint que produz efeito colateral é candidato a CSRF, mesmo os que parecem secundários.
A política de mesma origem, a base de tudo
Quase todas as defesas de CSRF se apoiam, no fundo, na política de mesma origem (same-origin policy) do navegador. Ela define que scripts de uma origem (esquema + host + porta) não podem ler dados de outra origem. É por isso que:
Note a assimetria crucial: a política impede ler, mas não impede enviar. Um formulário pode disparar um POST para qualquer origem; o que ele não pode é ver o que voltou. Entender essa fronteira explica por que o CSRF existe (o envio é permitido) e por que os tokens funcionam (a leitura é bloqueada). Essa mesma fronteira está no coração de outros temas de segurança web, e revisitá-la ajuda a raciocinar sobre o O que é XSS (Cross-Site Scripting)?, que justamente quebra a política ao injetar script dentro da origem-alvo.
CSRF em APIs e tokens
Em arquiteturas modernas baseadas em APIs, o cenário muda. Quando a autenticação usa um token enviado manualmente em um cabeçalho (por exemplo, Authorization: Bearer ...) em vez de um cookie automático, o CSRF clássico deixa de funcionar, porque o navegador não anexa esse cabeçalho sozinho em requisições cruzadas. Por isso, entender os mecanismos de O que é JWT (JSON Web Token)? ajuda a decidir o modelo de sessão. Ainda assim, APIs que usam cookies para sessão continuam vulneráveis e precisam das defesas acima — detalhamos o tema em Segurança de APIs: protegendo seus endpoints.
CORS não te protege de CSRF
Um equívoco perigoso e frequente: achar que ter CORS configurado defende contra CSRF. Não defende. O CORS controla se um script de outra origem pode ler a resposta de uma requisição cruzada — ele não impede que a requisição seja enviada nem que o servidor a processe. Um formulário autoenviável ou uma imagem dispara a requisição independentemente de CORS, e o efeito colateral acontece no servidor antes de qualquer checagem de leitura. CORS e CSRF resolvem problemas diferentes; não confunda um pelo outro.
Cookies modernos: a abordagem "__Host-"
Vale conhecer um detalhe que reforça a proteção de cookies de sessão: o prefixo __Host-. Um cookie nomeado com esse prefixo só é aceito pelo navegador se atender a condições estritas — Secure, sem atributo Domain (preso ao host exato) e com Path=/. Isso impede que um subdomínio comprometido sobrescreva o cookie de sessão (um ataque chamado cookie tossing), endurecendo o cenário same-site que discutimos.
Set-Cookie: __Host-sessao=abc123; Secure; HttpOnly; SameSite=Lax; Path=/Combinado com HttpOnly (que impede leitura por JavaScript e ajuda contra XSS), você obtém um cookie de sessão difícil de manipular tanto por CSRF quanto por scripts injetados.
Como testar se você está protegido
Validar a defesa é tão importante quanto implementá-la. Um roteiro prático de verificação:
Ferramentas de teste de segurança automatizam boa parte disso, mas entender o que cada checagem prova evita falsa sensação de segurança.
Erros comuns na proteção contra CSRF
Perguntas frequentes
Preciso de token CSRF se já uso SameSite=Strict? Para muitos apps, SameSite cobre o caso comum, mas a recomendação de segurança é manter as duas camadas, dada a variação entre navegadores e cenários same-site.
APIs com Authorization: Bearer precisam de proteção CSRF? Se a autenticação não depende de cookie automático, o CSRF clássico não se aplica. O risco volta se você usar cookies para a sessão.
CSRF pode roubar meus dados? Não diretamente. O atacante não lê a resposta; ele força ações. O dano é por efeito colateral (transferências, alterações), não por vazamento de leitura.
Token CSRF protege contra XSS? Não. São ataques distintos. E pior: um XSS bem-sucedido derrota a proteção CSRF. Trate as duas defesas como complementares.
Conclusão
O CSRF é engenhoso porque não quebra nada do lado do servidor: ele abusa de um comportamento legítimo do navegador, o envio automático de cookies. A boa notícia é que as defesas são bem estabelecidas. Use tokens anti-CSRF em operações que mudam estado, configure cookies de sessão com SameSite=Lax ou Strict, jamais altere estado com GET e considere a verificação de origem em ações críticas. Para fluxos baseados em tokens de cabeçalho, o risco quase desaparece. Aplicando essas camadas, você fecha uma das brechas mais silenciosas e exploradas da web.