A senha "qwerty123" não funciona mais: por que segurança não é chata
Imagine: você criou uma aplicação web incrível. Interface bonita, código reativo, tudo voa. Você a coloca no ar, registra o primeiro usuário — e uma hora depois seu banco de dados vaza para o público. História familiar? Infelizmente, autenticação segura em JavaScript é um tópico que muitos desenvolvedores deixam para depois. E é um erro.
Neste artigo, vamos abordar como proteger sua aplicação contra os ataques mais comuns: interceptação de tokens, XSS, CSRF e vazamento de senhas. Não vamos dar palestras sobre "deve-se fazer bem feito" — vamos mostrar código que você pode usar agora mesmo.
Pronto? Vamos lá.
Autenticação em JavaScript: por que o cliente é um campo de batalha
Quando falamos sobre autenticação na web, muitas vezes pensamos no backend: bancos de dados, sessões, hashes. Mas a autenticação JavaScript começa no cliente. E é aqui que as armadilhas nos esperam.
Tudo o que roda no navegador pode ser lido, modificado ou roubado. Seu código JavaScript é um livro aberto para um invasor que encontrou uma vulnerabilidade. Portanto, a primeira regra da autenticação segura é: nunca confie no cliente. Nunca.
Principais ameaças no lado do cliente
- XSS (Cross-Site Scripting) — um invasor insere um script que rouba tokens do localStorage.
- CSRF (Cross-Site Request Forgery) — o usuário está autenticado e um site malicioso envia requisições em nome dele.
- Man-in-the-Middle — interceptação de tráfego, se HTTPS não for usado.
- Vazamento de senhas — envio de senha em texto puro ou armazenamento no código.
Parece assustador? Na verdade, proteger-se contra isso não é tão difícil. O importante é saber quais ferramentas usar.
JWT: prático, mas com um porém
JWT (JSON Web Token) é um padrão para criar tokens de acesso. É leve, não requer armazenamento no servidor e é perfeito para SPAs. Mas sua popularidade o torna um alvo.
Muitos desenvolvedores armazenam JWT no localStorage. Isso é um erro. O localStorage é acessível por qualquer código JavaScript na página. Se você tiver pelo menos uma vulnerabilidade XSS — o token é roubado.
Como armazenar JWT corretamente
A melhor maneira é usar cookie httpOnly. Cookies com a flag httpOnly não são acessíveis via JavaScript. O XSS não os roubará. Mas há um detalhe: cookies são enviados automaticamente em cada requisição, o que torna a aplicação vulnerável a CSRF. A solução é usar SameSite e tokens CSRF.
Aqui está um exemplo de configuração de cookie httpOnly no backend (Node.js com Express):
// Servidor (Node.js / Express)res.cookie('token', jwtToken, { httpOnly: true, // Inacessível para JavaScript secure: true, // Apenas via HTTPS sameSite: 'strict', // Proteção contra CSRF maxAge: 3600000 // 1 hora});No cliente, você simplesmente envia as requisições — os cookies serão anexados automaticamente:
// Cliente (JavaScript)fetch('/api/profile', { method: 'GET', credentials: 'include' // Obrigatório!}).then(res => res.json()).then(data => console.log(data));Observe: credentials: 'include' — sem isso, os cookies não serão enviados para outra origem.
Hash de senhas: bcrypt para ajudar
Armazenar senhas em texto puro é como deixar as chaves de casa debaixo do tapete. Mesmo que seu site seja invadido, as senhas devem ser inúteis para o invasor.
bcrypt é um algoritmo de hash projetado especificamente para ser lento. Porque fazer o hash de uma senha para o usuário leva frações de segundo, mas para um ataque de força bruta leva anos. Em JavaScript (Node.js), use a biblioteca b