devly
Voltar para Secure Coding

Segredos no Cofre: Lidando com Senhas, Tokens e HTTPS

Aprenda a proteger os dados mais sensíveis da sua aplicação: senhas de usuários, tokens de acesso, chaves de API e a importância vital do HTTPS.

Atualizado em: 4 de Junho, 2025
Notas do Autor

Olá, Guardião(ã) dos Segredos! Na última aula, fortalecemos nosso código contra ataques comuns. Agora, vamos mergulhar em um dos aspectos mais críticos da segurança: proteger as chaves do reino – senhas, tokens, chaves de API e garantir que a comunicação seja sempre confidencial com HTTPS.

Gerenciar segredos de forma inadequada é como deixar a porta da frente da sua casa destrancada com um bilhete "Pode entrar!". Nesta aula, vamos aprender a construir um cofre digital robusto para sua aplicação.


1. Gerenciamento Seguro de Senhas 🔑

Senhas são a primeira linha de defesa para contas de usuário. Tratá-las com displicência é um convite a desastres. NUNCA, JAMAIS armazene senhas em texto plano ou de forma que possam ser facilmente revertidas.

Hashing de Senhas: A Prática Padrão

Hashing é o processo de transformar uma senha em uma string de caracteres aparentemente aleatória de tamanho fixo, usando um algoritmo matemático. O hash resultante não pode ser revertido para a senha original.

Use algoritmos de hashing fortes e modernos: Argon2 (preferencial), scrypt, bcrypt são os padrões atuais. Evite MD5 ou SHA1 para senhas.
Use um Salt ÚNICO por Usuário: Um salt é um valor aleatório adicionado à senha antes do hashing. Isso garante que duas senhas idênticas resultem em hashes diferentes, frustrando ataques de rainbow table.
Custo Computacional (Work Factor): Configure o algoritmo para ser computacionalmente caro (lento o suficiente para dificultar ataques de força bruta, mas rápido o suficiente para não prejudicar a UX).

Exemplo (Node.js com \`bcrypt\` - conceitual):

javascript
import bcrypt from 'bcrypt';

const saltRounds = 10; // Fator de custo. Ajuste conforme necessário.
const plainPassword = 'UserS3cur3P@sswOrd!';

// Gerar o hash (ao cadastrar usuário)
bcrypt.hash(plainPassword, saltRounds, function(err, hash) {
  if (err) { /* Tratar erro */ }
  // Armazene o 'hash' no banco de dados, NUNCA a plainPassword
  console.log('Hashed Password:', hash);
});

// Verificar a senha (ao fazer login)
const storedHashFromDB = '$2b$10$K9j3b...exampleHash...'; // Hash recuperado do BD
bcrypt.compare(plainPassword, storedHashFromDB, function(err, result) {
  if (err) { /* Tratar erro */ }
  if (result) {
    // Senha correta!
  } else {
    // Senha incorreta.
  }
});

Warning

Não Reinvente a Roda! Use bibliotecas de hashing bem estabelecidas e testadas pela comunidade para a sua linguagem/framework. Implementar hashing do zero é propenso a erros.

Políticas de Senha e Autenticação Multifator (MFA)

Além do hashing, boas políticas de senha e MFA são cruciais:

Requisitos de Complexidade: Mínimo de caracteres, combinação de maiúsculas, minúsculas, números e símbolos. Mas cuidado para não exagerar e prejudicar a usabilidade.
Verificação contra senhas vazadas: Use serviços como Have I Been Pwned para impedir que usuários escolham senhas já comprometidas.
Autenticação Multifator (MFA/2FA): SEMPRE ofereça e incentive o uso de MFA. É uma das defesas mais eficazes contra contas comprometidas, mesmo que a senha seja vazada.
Limitação de Tentativas de Login: Para mitigar ataques de força bruta.

Success

MFA é o seu melhor amigo! Priorize a implementação de MFA sobre políticas de rotação de senha excessivamente rigorosas, que muitas vezes levam os usuários a senhas mais fracas e previsíveis.

2. Lidando com Tokens e Chaves de API 🎟️

Aplicações modernas dependem de APIs, e estas são protegidas por chaves ou tokens. Vazá-los pode ser tão desastroso quanto vazar senhas de banco de dados.

Armazenamento Seguro: NUNCA comite chaves de API ou tokens diretamente no código fonte. Use variáveis de ambiente, arquivos de configuração fora do repositório (e no .gitignore), ou, idealmente, Secret Management Systems.
Tokens de Curta Duração: Configure tokens de sessão e acesso para expirarem em períodos razoáveis. Implemente refresh tokens para uma melhor UX, mas também com segurança.
Escopo Mínimo (Princípio do Menor Privilégio): Crie chaves de API com as permissões estritamente necessárias para a tarefa que irão realizar. Não use uma chave com acesso total se ela só precisa ler dados.
Monitoramento e Revogação: Tenha mecanismos para monitorar o uso de chaves e tokens e para revogá-los rapidamente em caso de comprometimento.

Exemplo (Node.js - Acessando uma API Key de variável de ambiente):

javascript
// Em algum lugar no seu código de backend
const apiKey = process.env.MY_API_SERVICE_KEY;

if (!apiKey) {
  console.error('Chave de API MY_API_SERVICE_KEY não configurada!');
  // Tratar a ausência da chave (ex: desabilitar funcionalidade, lançar erro)
}

fetch(`https://api.service.com/data?key=${apiKey}`)
  .then(res => res.json())
  .then(data => { /* ... */ });

// No seu terminal, antes de rodar a aplicação:
// export MY_API_SERVICE_KEY="suaChaveSuperSecretaAqui" (Linux/macOS)
// set MY_API_SERVICE_KEY="suaChaveSuperSecretaAqui" (Windows CMD)
// $Env:MY_API_SERVICE_KEY="suaChaveSuperSecretaAqui" (Windows PowerShell)

Info

Para aplicações em produção, especialmente em ambientes de nuvem, use Secret Management Systems dedicados, como AWS Secrets Manager, HashiCorp Vault, Google Cloud Secret Manager ou Azure Key Vault. Eles oferecem armazenamento seguro, controle de acesso, rotação e auditoria de segredos.

3. HTTPS é Inegociável 🔒

Todo o tráfego entre o navegador do usuário e seu servidor DEVE ser criptografado usando HTTPS (HTTP sobre TLS/SSL). Sem HTTPS, dados sensíveis (senhas, informações pessoais, cookies de sessão) trafegam em texto plano, vulneráveis à interceptação (ataques Man-in-the-Middle).

Confidencialidade: Criptografa os dados, impedindo que bisbilhoteiros os leiam.
Integridade: Garante que os dados não foram alterados durante a transmissão.
Autenticação (do servidor): Permite que o navegador verifique se está se comunicando com o servidor legítimo através de certificados SSL/TLS.
SEO e Confiança: Navegadores marcam sites HTTP como 'Não Seguros', e HTTPS é um fator de ranking no Google.

Como Funciona (Muito Simplificado)

Quando você acessa um site HTTPS, seu navegador e o servidor realizam um 'handshake' TLS. O servidor apresenta um certificado digital (emitido por uma Autoridade Certificadora - CA), o navegador o valida e, se tudo estiver OK, eles negociam chaves de criptografia para proteger a sessão.

Próximos Passos com HTTPS: HSTS

HTTP Strict Transport Security (HSTS) é um cabeçalho de resposta HTTP que instrui os navegadores a sempre se conectarem ao seu site usando HTTPS, mesmo que o usuário digite \`http://\` ou clique em um link HTTP. Isso protege contra ataques de SSL stripping.

http
// Exemplo de cabeçalho HSTS
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Success

Configure o redirecionamento de todo tráfego HTTP para HTTPS no seu servidor web (Nginx, Apache, etc.) ou balanceador de carga. Em seguida, implemente o cabeçalho HSTS. Obter certificados SSL/TLS é fácil e muitas vezes gratuito com serviços como Let's Encrypt.

💊 Pílula Devly

Senhas fortes e bem guardadas, tokens tratados como ouro e HTTPS em tudo: esses são os pilares para proteger os segredos da sua aplicação. A segurança dos dados mais sensíveis não é um luxo, é uma responsabilidade fundamental. Ao adotar essas práticas, você constrói confiança com seus usuários e fortalece a reputação da sua aplicação (e a sua como dev!).

Anterior

Escrevendo Código que Resiste: Input Validation, Output Encoding e Mais

Voltar

Próximo

APIs Blindadas e Dependências Vigiadas

Continuar