Prevenindo requisições CSRF em JavaScript

Descubra como prevenir ataques CSRF em JavaScript e garantir que suas requisições sejam seguras.

Como evitar requisições CSRF no JavaScript?

CSRF (Cross-Site Request Forgery) é um ataque onde um atacante consegue fazer com que um usuário autenticado execute ações indesejadas em uma aplicação web, sem o seu consentimento. Esse ataque ocorre quando o navegador do usuário envia uma requisição para um servidor em nome dele, usando sua autenticação, sem que o usuário saiba. Em JavaScript, é importante entender como proteger sua aplicação contra CSRF, uma vez que esse tipo de ataque pode comprometer a integridade dos dados do usuário.

Como funciona um ataque CSRF?

Imagine que um usuário está logado em um site de banco, com uma sessão ativa. Se ele visita um site malicioso enquanto está logado, esse site pode fazer com que o navegador envie uma requisição de transferência de fundos para o servidor do banco, usando a sessão do usuário sem o seu conhecimento.

Exemplo de ataque CSRF:

// Um site malicioso faz uma requisição para transferir fundos
fetch('https://www.banco.com/transferencia', {
  method: 'POST',
  body: JSON.stringify({ destino: 'conta-maliciosa', valor: '1000' }),
  headers: {
    'Content-Type': 'application/json'
  }
});

Neste exemplo, o atacante faz uma requisição para o servidor bancário, utilizando a sessão do usuário logado, realizando a transferência de forma indesejada. O servidor não verifica se a requisição é legítima ou não.

Como proteger contra CSRF?

Existem várias formas de proteger uma aplicação web contra ataques CSRF. Vamos explorar as melhores práticas para evitar esse tipo de vulnerabilidade em suas requisições JavaScript:

  1. Usar tokens CSRF (Anti-CSRF tokens) A forma mais comum de prevenção de ataques CSRF é o uso de tokens CSRF. O servidor gera um token único para cada sessão de usuário e envia esse token junto com a resposta. O cliente deve incluir esse token em cada requisição que modifica dados no servidor. O servidor então verifica se o token enviado com a requisição corresponde ao token armazenado na sessão do usuário.

Exemplo de uso de token CSRF em uma requisição:

let tokenCSRF = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

fetch('https://www.banco.com/transferencia', {
  method: 'POST',
  body: JSON.stringify({ destino: 'conta-maliciosa', valor: '1000' }),
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': tokenCSRF
  }
});

Neste exemplo, o token CSRF é retirado do meta tag da página e adicionado ao cabeçalho da requisição. O servidor verifica se o token recebido é válido antes de processar a requisição.

  1. Validar o referer e a origem das requisições Outra medida importante é verificar o cabeçalho Referer ou Origin de todas as requisições que modificam dados no servidor. O servidor deve garantir que o Referer ou Origin seja o mesmo domínio da aplicação, garantindo que a requisição foi feita pela própria aplicação e não por um site malicioso.

Exemplo de verificação de origem no servidor (Node.js):

if (req.headers.origin !== 'https://www.seudominio.com') {
  return res.status(403).send('Requisição não permitida.');
}

Essa verificação ajuda a garantir que as requisições não sejam originadas de domínios desconhecidos.

  1. Utilizar o cabeçalho SameSite para cookies Os navegadores modernos oferecem um recurso chamado SameSite para cookies, que limita o envio de cookies em requisições entre sites. Definir o atributo SameSite como Strict ou Lax ajuda a evitar que cookies de sessão sejam enviados em requisições de sites externos, reduzindo o risco de CSRF.

Exemplo de configuração de cookie com SameSite:

res.cookie('session_id', 'valorDoCookie', { httpOnly: true, secure: true, sameSite: 'Strict' });

Neste exemplo, o cookie session_id será enviado apenas se a requisição for feita a partir do mesmo domínio, dificultando o ataque CSRF.

  1. Validar todos os dados no backend Embora a prevenção no frontend seja importante, é crucial validar todos os dados no backend. Isso significa que o servidor deve sempre verificar os dados recebidos em cada requisição antes de realizar qualquer ação sensível. Nunca confie apenas nos dados enviados pelo cliente, pois esses dados podem ser manipulados por um atacante.

  2. Usar métodos HTTP seguros Evite usar o método GET para ações que alteram o estado do servidor, como atualizar ou excluir dados. O método GET deve ser usado apenas para requisições de leitura, enquanto métodos como POST, PUT e DELETE devem ser usados para modificar dados. Isso ajuda a garantir que ações sensíveis não possam ser feitas por meio de links maliciosos ou prefetching de páginas.

Conclusão

A proteção contra CSRF é essencial para a segurança de suas aplicações web. Ao adotar boas práticas como o uso de tokens CSRF, a verificação de origem das requisições e o uso adequado do cabeçalho SameSite para cookies, você reduz significativamente os riscos de ataques CSRF. Lembre-se de validar todos os dados no backend e de usar métodos HTTP seguros para garantir a integridade da sua aplicação e a segurança dos seus usuários.

Proteger sua aplicação contra CSRF não é apenas sobre implementar tokens, mas também garantir que as requisições sejam legítimas e originadas de fontes confiáveis. Adotar uma abordagem holística de segurança que inclua validação, tokens e políticas de cookies é essencial para garantir que sua aplicação esteja protegida contra esses ataques.

Algumas aplicações:

  • Garantir que todas as requisições que alteram dados no servidor sejam protegidas com tokens CSRF e validação adequada.
  • Usar o cabeçalho SameSite para proteger cookies e impedir que eles sejam enviados com requisições de outros domínios.
  • Validar o cabeçalho Referer e Origin de todas as requisições para garantir que a requisição venha de uma origem confiável.
  • Evitar o uso de GET para ações que alteram o estado do servidor e sempre usar métodos POST, PUT ou DELETE para essas ações.

Dicas para quem está começando

  • Ao usar tokens CSRF, sempre associe o token a uma sessão única e verifique se ele corresponde no servidor.
  • Evite enviar senhas ou informações sensíveis através de URLs, sempre use cabeçalhos adequados.
  • Testar sua aplicação com ferramentas que simulem ataques CSRF pode ajudá-lo a garantir que sua proteção esteja funcionando corretamente.
  • Se possível, use métodos HTTP seguros como POST, PUT e DELETE para todas as requisições que alteram o estado da aplicação.

Contribuições de Cláudia Medeiros

Compartilhe este tutorial: Como evitar requisições CSRF no JavaScript?

Compartilhe este tutorial

Continue aprendendo:

Como armazenar senhas de forma segura no frontend?

Entenda as melhores práticas para armazenar senhas de forma segura no frontend, protegendo os dados do usuário contra vulnerabilidades.

Tutorial anterior

Como minimizar o tempo de execução do JavaScript para melhorar performance?

Entenda como minimizar o tempo de execução do JavaScript, melhorar o desempenho do seu código e otimizar a experiência do usuário.

Próximo tutorial