Entendendo CSRF em Profundidade
Fornece uma exploração aprofundada dos ataques de Cross-Site Request Forgery (CSRF), explicando suas mecânicas, demonstrando exemplos e detalhando vários métodos de prevenção para melhorar a segurança de aplicações web.
Ao trabalhar com desenvolvimento web, especialmente com cookies, frequentemente ouvimos frases como "esta configuração ajuda a prevenir CSRF". No entanto, muitas pessoas têm apenas uma noção vaga do que "CSRF" realmente significa.
Hoje, vamos nos aprofundar no CSRF (Cross-Site Request Forgery), uma falha comum de segurança na web. Isso nos ajudará a lidar mais efetivamente com problemas relacionados a CSRF.
O que é CSRF?
CSRF (Cross-Site Request Forgery) é um tipo de ataque na web onde os atacantes enganam usuários autenticados para executar ações não intencionais. Em termos simples, é "hackers fingindo ser usuários para realizar ações não autorizadas".
Como funciona o CSRF
Para entender o CSRF, precisamos compreender alguns conceitos chave:
Política de Mesma Origem do Navegador
A política de mesma origem é um recurso de segurança nos navegadores que limita como um documento ou script de uma origem pode interagir com recursos de outra origem.
Uma origem consiste em um protocolo (como HTTP ou HTTPS), nome de domínio e número de porta. Por exemplo, https://example.com:443
é uma origem, enquanto https://demo.com:80
é outra.
A política de mesma origem restringe o acesso a dados entre páginas de diferentes origens, significando que:
- JavaScript de uma origem não pode ler o DOM de outra origem
- JavaScript de uma origem não pode ler os Cookies, IndexedDB ou localStorage de outra origem
- JavaScript de uma origem não pode enviar solicitações AJAX para outra origem (a menos que use CORS)
No entanto, para manter a abertura e a interoperabilidade da Web (como carregar recursos de CDNs ou enviar solicitações para APIs de terceiros para registro), a política de mesma origem não restringe solicitações de rede cross-origin:
- Páginas podem enviar solicitações GET ou POST para qualquer origem (como carregar imagens ou enviar formulários)
- Recursos de qualquer origem podem ser incluídos (como tags
<script>
,<img>
,<link>
,<iframe>
)
Mecanismo de envio automático de cookies
O mecanismo de envio automático de cookies é um recurso importante dos navegadores. Quando um navegador envia uma solicitação para um domínio, ele automaticamente anexa todos os cookies para esse domínio. Este processo é automático e não requer nenhum código JavaScript ou interação do usuário.
Este mecanismo permite que os sites se lembrem facilmente do status de login dos usuários, pois cada solicitação carrega automaticamente as informações de identidade do usuário.
Negrito
Por exemplo, quando você faz login em um site bancário (bank.com
) e obtém um cookie de identidade, ao clicar para ver seu extrato, o navegador automaticamente encontra todos os cookies correspondentes a bank.com
e os anexa à solicitação do extrato. O servidor do banco pode então identificar você no backend e retornar suas informações de extrato.
Etapas do ataque CSRF
-
O usuário faz login no site alvo (como um site bancário) e obtém um cookie de autenticação. Esta etapa usa o mecanismo de envio automático de cookies. Após o site bancário definir um cookie de autenticação de identidade, o navegador automaticamente anexa este cookie para cada solicitação enviada para esse site.
-
Sem fazer logout, o usuário visita um site malicioso. Neste ponto, devido à política de mesma origem, o site malicioso não pode ler ou modificar diretamente o cookie do site bancário. Isso protege as informações de identidade do usuário de serem roubadas diretamente.
-
O site malicioso inclui uma solicitação para o site alvo (como uma operação de transferência). Embora a política de mesma origem restrinja o acesso cross-origin, ela permite solicitações de rede cross-origin, como solicitações iniciadas através de tags
<img>
,<form>
. Os atacantes exploram essa "brecha". -
O navegador do usuário automaticamente envia essa solicitação, junto com o cookie do site alvo. Este é o núcleo do ataque CSRF. Ele tira proveito tanto da política de mesma origem permitindo solicitações cross-origin quanto do mecanismo de envio automático de cookies (mesmo solicitações acionadas por sites maliciosos levarão cookies correspondentes ao domínio).
-
O site alvo recebe a solicitação, verifica se o cookie é válido e executa a operação. O servidor não consegue dizer se essa solicitação veio de uma ação legítima do usuário porque o cookie anexado é válido.
Exemplo de ataque CSRF
Vamos ilustrar como um ataque CSRF acontece com um exemplo específico. Usaremos um site bancário fictício bank.com
como exemplo.
Primeiro, o usuário visita https://bank.com
e faz login em sua conta.
Após o login bem-sucedido, o servidor define um cookie de autenticação, por exemplo:
O usuário realiza uma operação de transferência no site bancário, por exemplo, transferindo $1000 para Alice. Esta operação pode enviar uma solicitação como esta:
Agora, suponha que um atacante crie um site malicioso https://evil.com
contendo o seguinte HTML:
Quando o usuário clica no link https://evil.com
sem sair de sua conta no banco, porque ele já está logado em bank.com
, o navegador tem um cookie session_id
válido.
Depois que a página maliciosa carrega, ela automaticamente envia o formulário oculto, enviando uma solicitação de transferência para https://bank.com/transfer
.
O navegador do usuário automaticamente anexa o cookie bank.com
a esta solicitação. O servidor do bank.com
recebe a solicitação, verifica se o cookie é válido e então executa esta operação de transferência não autorizada.
Métodos comuns para prevenir ataques CSRF
Aqui estão vários métodos de defesa contra CSRF comumente usados. Explicaremos em detalhe o princípio de cada método e como ele previne efetivamente ataques CSRF:
Usar tokens CSRF
Tokens CSRF são um dos métodos mais comuns e eficazes para defender contra ataques CSRF. Veja como funciona:
- O servidor gera um token único e imprevisível para cada sessão.
- Este token é incorporado em todos os formulários para operações sensíveis.
- Quando o usuário envia um formulário, o servidor verifica a validade do token.
Como o token CSRF é um valor único vinculado à sessão do usuário, e o atacante não pode saber ou adivinhar esse valor (pois é diferente para cada sessão), mesmo que o atacante engane o usuário para enviar uma solicitação, a solicitação será rejeitada pelo servidor devido à falta de um token CSRF válido.
Exemplo de implementação:
No lado do servidor (usando Node.js e Express):
No JavaScript frontend:
Verificando o cabeçalho Referer
O cabeçalho Referer
contém a URL da página que iniciou a solicitação. Verificando o cabeçalho Referer
, o servidor pode determinar se a solicitação vem de uma fonte legítima.
Como os ataques CSRF geralmente vêm de domínios diferentes, o cabeçalho Referer
mostrará o nome de domínio do atacante. Verificando se o Referer
é o valor esperado, solicitações de fontes desconhecidas podem ser bloqueadas.
No entanto, vale a pena notar que este método não é totalmente confiável, pois alguns navegadores podem não enviar o cabeçalho Referer, e os usuários podem desabilitar o cabeçalho Referer por meio de configurações do navegador ou plugins.
Exemplo de implementação:
Usando o atributo de cookie SameSite
SameSite
é um atributo de cookie usado para controlar se os cookies são enviados com solicitações de sites cruzados. Tem três valores possíveis:
Strict
: Cookies são enviados apenas em solicitações de mesma origem.Lax
: Cookies são enviados em solicitações de mesma origem e navegação de nível superior.None
: Cookies são enviados em todas as solicitações de sites cruzados (deve ser usado com o atributoSecure
).
Quando SameSite
é definido como Strict
, ele pode impedir completamente que sites de terceiros enviem cookies, assim efetivamente prevenindo ataques CSRF.
Se SameSite
for definido como Lax
, ele protege operações sensíveis, permitindo ao mesmo tempo alguns casos de uso cross-site comuns (como entrar em um site a partir de links externos).
Exemplo de implementação:
Usando cabeçalhos de solicitação personalizados
Para solicitações AJAX, cabeçalhos de solicitação personalizados podem ser adicionados. Devido às restrições da política de mesma origem, os atacantes não podem definir cabeçalhos personalizados em solicitações cross-origin. O servidor pode verificar a presença deste cabeçalho personalizado para verificar a legitimidade da solicitação.
Exemplo de implementação:
No frontend:
No lado do servidor:
Verificação de cookies duplos
A verificação de cookies duplos é uma técnica eficaz de defesa contra CSRF. Seu princípio central é que o servidor gera um token aleatório, define-o tanto como um cookie quanto o incorpora na página (geralmente como um campo de formulário oculto). Quando o navegador envia uma solicitação, ele automaticamente inclui o cookie, enquanto o JavaScript da página envia o token como um parâmetro de solicitação. O servidor então verifica se o token no cookie corresponde ao token nos parâmetros de solicitação.
Embora os atacantes possam incluir o cookie do site alvo em solicitações cross-site, eles não podem ler ou modificar o valor do cookie, nem acessar ou modificar o valor do token na página. Exigindo que a solicitação inclua tokens tanto do cookie quanto dos parâmetros, garante que a solicitação venha de uma fonte com permissão para ler o cookie, assim defendendo efetivamente contra ataques CSRF.
Usando re-autenticação para operações sensíveis
Para operações particularmente sensíveis (como mudar senhas ou fazer transferências grandes), os usuários podem ser obrigados a re-autenticar. Isso fornece aos usuários um ponto de verificação de segurança adicional. Mesmo se um usuário iniciar com sucesso um ataque CSRF, ele não poderá passar pela etapa de re-autenticação.
Sugestões de implementação:
- Antes de realizar operações sensíveis, redirecione para uma página de autenticação separada.
- Nesta página, exija que o usuário insira sua senha ou outras informações de verificação de identidade.
- Após a verificação ser aprovada, gere um token de uso único e use este token nas operações sensíveis subsequentes.
Resumo
Através desta discussão aprofundada, esperamos que agora você tenha uma compreensão mais abrangente dos ataques CSRF. Não só aprendemos como o CSRF funciona, mas também exploramos várias medidas de defesa eficazes. Todos esses métodos podem efetivamente aumentar a segurança das aplicações web.
Espero que este conhecimento ajude você a lidar melhor com questões relacionadas a CSRF em seu desenvolvimento diário e construir aplicações web mais seguras.