Compreender CSRF em profundidade
Oferece uma exploração aprofundada sobre os ataques de Cross-Site Request Forgery (CSRF), explicando os seus mecanismos, demonstrando exemplos e detalhando vários métodos de prevenção para melhorar a segurança das aplicações web.
Quando trabalhamos em desenvolvimento web, especialmente com cookies, ouvimos frequentemente frases como "esta configuração ajuda a prevenir CSRF". No entanto, muitas pessoas têm apenas uma ideia vaga do que "CSRF" realmente significa.
Hoje, vamos mergulhar profundamente no CSRF (Cross-Site Request Forgery), uma falha comum de segurança na web. Isso nos ajudará a lidar com questões relacionadas ao CSRF de forma mais eficaz.
O que é CSRF?
CSRF (Cross-Site Request Forgery) é um tipo de ataque web onde os atacantes enganam utilizadores autenticados a realizar ações não intencionais. Em termos simples, é "hackers fingindo ser utilizadores para realizar ações não autorizadas".
Como o CSRF funciona
Para entender o CSRF, precisamos compreender alguns conceitos-chave:
Política de mesmo origem do navegador
A política de mesmo origem é uma funcionalidade 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 da porta. Por exemplo, https://example.com:443
é uma origem, enquanto https://demo.com:80
é outra.
A política de mesmo 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 o Cookie, IndexedDB, ou localStorage de outra origem
- JavaScript de uma origem não pode enviar pedidos AJAX para outra origem (a menos que use CORS)
No entanto, para manter a abertura e interoperabilidade da Web (como carregar recursos de CDNs ou enviar pedidos para APIs de terceiros para registo), a política de mesmo origem não restringe pedidos de rede entre origens:
- Páginas podem enviar pedidos GET ou POST para qualquer origem (como carregar imagens ou submeter formulários)
- Recursos de qualquer origem podem ser incluídos (como tags
<script>
,<img>
,<link>
,<iframe>
)
Mecanismo automático de envio de cookies
O mecanismo automático de envio de cookies é uma funcionalidade importante dos navegadores. Quando um navegador envia um pedido a 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 utilizador.
Este mecanismo permite que os websites lembrem facilmente o estado de login dos utilizadores porque cada pedido automaticamente carrega as informações de identidade do utilizador.
Negrito
Por exemplo, quando faz login num website de banco (bank.com
) e obtém um cookie de identidade, quando clica para ver o seu extrato, o navegador automaticamente encontra todos os cookies correspondentes a bank.com
e os anexa ao pedido de extrato. O servidor do banco pode então identificá-lo a partir do backend e retornar suas informações de extrato.
Passos de ataque CSRF
-
O utilizador faz login no site alvo (como um site de banco) e obtém um cookie de autenticação. Este passo usa o mecanismo de envio automático de cookies. Depois de o site do banco definir um cookie de autenticação de identidade, o navegador anexará automaticamente este cookie a cada pedido enviado para esse site.
-
Sem fazer logout, o utilizador visita um site malicioso. Neste ponto, devido à política de mesmo origem, o site malicioso não pode diretamente ler ou modificar o cookie do site do banco. Isso protege as informações de identidade do utilizador de serem diretamente roubadas.
-
O site malicioso inclui um pedido para o site alvo (como uma operação de transferência). Embora a política de mesmo origem restrinja o acesso entre origens, ela permite pedidos de rede entre origens, como pedidos iniciados através de tags
<img>
,<form>
. Os atacantes exploram essa "brecha". -
O navegador do utilizador envia automaticamente este pedido, junto com o cookie do site alvo. Este é o núcleo do ataque CSRF. Ele aproveita tanto a política de mesmo origem permitindo pedidos entre origens e o mecanismo de envio automático de cookies (mesmo pedidos acionados por sites maliciosos carregam cookies correspondentes ao domínio).
-
O site alvo recebe o pedido, verifica se o cookie é válido, e executa a operação. O servidor não consegue distinguir se este pedido vem de uma ação legítima do utilizador porque o cookie anexado é válido.
Exemplo de ataque CSRF
Vamos ilustrar como acontece um ataque CSRF com um exemplo específico. Usaremos um website de banco fictício bank.com
como exemplo.
Primeiro, o utilizador visita https://bank.com
e faz login na sua conta.
Após um login bem-sucedido, o servidor define um cookie de autenticação, por exemplo:
O utilizador realiza uma operação de transferência no website do banco, digamos transferindo $1000 para Alice. Esta operação pode enviar um pedido como este:
Agora, suponha que um atacante crie um website malicioso https://evil.com
contendo o seguinte HTML:
Quando o utilizador clica no link https://evil.com
sem fazer logout da sua conta bancária, como ele já está logado em bank.com
, o navegador possui um cookie session_id
válido.
Depois que a página maligna carrega, ela submete automaticamente o formulário oculto, enviando um pedido de transferência para https://bank.com/transfer
.
O navegador do utilizador anexa automaticamente o cookie bank.com
a este pedido. O servidor bank.com
recebe o pedido, 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 comuns de defesa contra CSRF. Iremos explicar em detalhe o princípio de cada método e como ele efetivamente previne ataques CSRF:
Usar tokens CSRF
Os 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 utilizador envia um formulário, o servidor verifica a validade do token.
Porque o token CSRF é um valor único vinculado à sessão do utilizador, e o atacante não pode saber ou adivinhar este valor (pois é diferente para cada sessão), mesmo que o atacante engane o utilizador para enviar um pedido, o pedido será rejeitado 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 de frontend:
Verificação do cabeçalho Referer
O cabeçalho Referer
contém a URL da página que iniciou o pedido. Ao verificar o cabeçalho Referer
, o servidor pode determinar se o pedido vem de uma fonte legítima.
Como os ataques CSRF geralmente vêm de domínios diferentes, o cabeçalho Referer
mostrará o nome do domínio do atacante. Ao verificar se o Referer
é o valor esperado, é possível bloquear pedidos de fontes desconhecidas.
No entanto, vale notar que este método não é completamente confiável, pois alguns navegadores podem não enviar o cabeçalho Referer, e os utilizadores podem desativá-lo através das configurações do navegador ou plugins.
Exemplo de implementação:
Usar o atributo SameSite
cookie
SameSite
é um atributo de cookie usado para controlar se cookies são enviados com pedidos entre sites. Possui três valores possíveis:
Strict
: Cookies são enviados apenas em pedidos de mesmo site.Lax
: Cookies são enviados em pedidos de mesmo site e navegação de nível superior.None
: Cookies são enviados em todos os pedidos entre sites (deve ser usado com o atributoSecure
).
Quando SameSite
é definido como Strict
, ele pode prevenir completamente que sites de terceiros enviem cookies, prevenindo assim eficazmente ataques CSRF.
Se SameSite
estiver definido como Lax
, ele protege operações sensíveis enquanto permite alguns casos comuns de uso entre sites (como entrar em um site a partir de links externos).
Exemplo de implementação:
Usar cabeçalhos de pedido personalizados
Para pedidos AJAX, cabeçalhos de pedido personalizados podem ser adicionados. Devido às restrições da política de mesmo origem, atacantes não podem definir cabeçalhos personalizados em pedidos entre origens. O servidor pode verificar a presença deste cabeçalho personalizado para verificar a legitimidade do pedido.
Exemplo de implementação:
No frontend:
No lado do servidor:
Verificação dupla de cookies
A verificação dupla de cookies é uma técnica eficaz de defesa contra CSRF. O seu princípio central é que o servidor gera um token aleatório, o define como um cookie e o incorpora na página (geralmente como um campo de formulário oculto). Quando o navegador envia um pedido, ele inclui automaticamente o cookie, enquanto o JavaScript da página envia o token como um parâmetro de pedido. O servidor então verifica se o token no cookie corresponde ao token nos parâmetros do pedido.
Embora atacantes possam incluir o cookie do website alvo em pedidos entre sites, eles não podem ler ou modificar o valor do cookie, nem podem acessar ou modificar o valor do token na página. Ao exigir que o pedido inclua tokens tanto do cookie quanto dos parâmetros, garante-se que o pedido venha de uma fonte com permissão para ler o cookie, defendendo assim eficazmente contra ataques CSRF.
Usar re-autenticação para operações sensíveis
Para operações particularmente sensíveis (como alterar senhas ou realizar grandes transferências), pode-se exigir que os utilizadores façam re-autenticação. Isso fornece aos utilizadores um ponto de verificação de segurança adicional. Mesmo que um utilizador inicie com sucesso um ataque CSRF, não poderá passar na etapa de re-autenticação.
Sugestões de implementação:
- Antes de realizar operações sensíveis, redirecionar para uma página de autenticação separada.
- Nesta página, exigir que o utilizador insira a sua senha ou outras informações de verificação de identidade.
- Após a verificação passar, gerar um token de uso único e usar este token nas operações sensíveis subsequentes.
Resumo
Através desta discussão aprofundada, esperamos que agora tenha uma compreensão mais abrangente dos ataques CSRF. Não apenas aprendemos como o CSRF funciona, mas também exploramos várias medidas eficazes de defesa. Todos estes métodos podem efetivamente aumentar a segurança das aplicações web.
Esperamos que este conhecimento ajude você a lidar melhor com questões relacionadas ao CSRF no seu desenvolvimento diário e a construir aplicações web mais seguras.