In this article
9 práticas recomendadas para armazenar senhas
Armazenar senhas com segurança é um desafio para qualquer organização — de pequenas startups a grandes corporações.
Em startups recém-fundadas, a falta de recursos pode levar à contratação inicial de desenvolvedores iniciantes, sem experiência aprofundada em práticas adequadas de armazenamento de senhas. Como a autenticação costuma ser adicionada logo no início do processo de desenvolvimento, isso pode resultar em práticas inadequadas para armazenar senhas.
Isso leva a implementações abaixo do ideal, que acabam servindo de base para a aplicação. E, quanto mais central for um módulo para a aplicação, menor será a disposição do desenvolvedor para alterá-lo mais adiante no projeto, por medo de causar problemas.
Assim, a implementação inadequada da autenticação vai sendo mantida até que algo dê errado e alguém consiga roubar as senhas dos seus usuários.
As práticas recomendadas de segurança de aplicações são fundamentais durante o desenvolvimento para prevenir invasões aos sistemas. Mas nada é 100% seguro, então você precisa tomar medidas para proteger as senhas dos seus usuários.
Neste artigo, vamos abordar as práticas mais importantes para armazenar senhas.
1. Proteja seus bancos de dados e contêineres
A segurança de bancos de dados não é uma prática recomendada apenas para o armazenamento de senhas. Ela se aplica a todos os dados armazenados no banco e, por isso, não deve ser negligenciada.
Se um invasor não conseguir acessar seus dados, também não poderá descriptografá-los. Por isso, consulte também as práticas recomendadas de segurança do fornecedor do seu banco de dados.
É claro que isso vale para todos os seus sistemas, não apenas para os bancos de dados. Se você usa um mecanismo de contêiner popular, como o Docker, fica exposto a todos os problemas associados a ele. Portanto, não negligencie a segurança de contêineres e monitore seus sistemas conforme necessário.
Segurança de contêineres que prioriza os desenvolvedores
O Snyk encontra e corrige automaticamente vulnerabilidades em imagens de contêiner e workloads do Kubernetes.
2. Faça o hash de todas as senhas
Nunca armazene senhas em texto simples. Sempre gere um hash a partir delas e armazene o hash. No armazenamento de senhas, o hashing é superior à criptografia, pois não é possível reverter um hash.
Quando um usuário tentar fazer login, você poderá gerar novamente o hash a partir da senha digitada e verificar se ele corresponde ao hash salvo no cadastro. Ninguém com acesso ao banco de dados conseguirá ler nem adivinhar a senha original a partir desse hash, nem mesmo você ou seus colegas de trabalho. Usar um hash também significa que não há uma chave de criptografia que possa ser roubada.
3. Use uma função hash robusta
Nem todas as funções hash são iguais. Algumas não são seguras do ponto de vista criptográfico, e outras foram criadas para serem calculadas rapidamente — o que você deve evitar ao gerar hashes de senhas.
Funções hash que podem ser calculadas rapidamente permitem que invasores testem à força muitas combinações aleatórias até encontrar as senhas ocultas nos hashes. Você precisa dificultar esse trabalho. Embora também precise usar essas funções lentas para gerar o hash da senha no cadastro ou no login, não terá que aplicá-las a milhões de combinações aleatórias.
A OWASP recomenda usar Argon2 para gerar hashes de senhas. Se não estiver disponível, use bcrypt; se bcrypt não estiver disponível, use scrypt.
4. Adicione um salt às senhas
Adicionar um salt à senha significa acrescentar a ela uma sequência aleatória antes de gerar o hash. Isso garante que os hashes de senhas conhecidas não sejam iguais. Um invasor pode ter uma tabela com essas senhas e seus hashes correspondentes e simplesmente consultá-la para verificar quais foram usadas pelos seus usuários. Essa tabela pode conter o hash da senha password, mas não o de &()/&IJDNSBAEpassword.
Os usuários também costumam reutilizar a mesma senha em vários aplicativos. Se um invasor tiver acesso a senhas vazadas de vários aplicativos populares, adicionar um salt antes de gerar os hashes impedirá que ele consiga compará-las.
A sequência do salt é armazenada junto com a senha no banco de dados. Bibliotecas modernas de hashing, como Argon2 e bcrypt, adicionam salts às senhas automaticamente antes de gerar os hashes.
5. Adicione um pepper às senhas
Adicionar um pepper às senhas funciona da mesma forma que adicionar um salt: você acrescenta uma sequência aleatória antes de gerar o hash.
A diferença é que, no caso do pepper, a sequência é a mesma para todas as senhas, mas não fica armazenada junto delas no banco de dados. Em vez disso, você precisa armazená-la no sistema de arquivos ou em um armazenamento de objetos. Pode ser em qualquer lugar, desde que não seja no mesmo local que o banco de dados de senhas.
Se um hacker conseguir acessar seu banco de dados, ainda faltará uma parte dos dados, o que tornará muito mais difícil relacionar os hashes das senhas às senhas corretas.
6. Atualize os fatores de trabalho
Embora as funções hash levem algum tempo para executar, o avanço da velocidade de processamento dos computadores também acelera esse processo. Uma operação de geração de hash que levava alguns segundos quando o código foi escrito pode levar apenas milissegundos para um invasor com um computador mais potente.
Para contornar esse problema, as funções hash têm um parâmetro chamado “fator de trabalho”. Esse parâmetro faz com que a função execute mais iterações no hash e, consequentemente, demore mais.
Há dois pontos a considerar em relação aos fatores de trabalho. Por um lado, você não quer facilitar demais o hashing para um invasor; por outro, não quer dificultar demais o login. Em geral, evite escolher fatores de trabalho extremamente altos.
Se você atualizar sua infraestrutura e seus servidores ficarem mais potentes, também deverá aumentar os fatores de trabalho para que sua segurança aproveite esse ganho de desempenho.
7. Não obrigue os usuários a redefinir as senhas
Antigamente, era considerada uma prática recomendada obrigar os usuários a trocar de senha a cada poucas semanas. A ideia era fazer com que senhas roubadas tivessem prazo de validade. Na prática, porém, isso só frustrava os usuários e os levava a escolher senhas mais simples e menos seguras.
Se você precisa seguir essa prática ultrapassada por exigências de conformidade, não há como evitá-la. Mas, se nenhum fator externo exigir que você siga essas diretrizes, não obrigue seus usuários a trocar de senha. A longo prazo, isso ajudará a manter a qualidade das senhas.
8. Verifique o tamanho das senhas, não a complexidade
Em geral, o tamanho da senha é mais importante do que a complexidade. Quanto mais longa a senha, mais tempo será necessário para descobri-la por meio de ataques automatizados — em alguns casos, anos. Isso pode ser uma vantagem, pois é muito mais fácil lembrar IonceateahamburgerinLondon do que x5§.11#.
Por isso, não exija que os usuários usem números ou caracteres especiais. Deixe que escrevam o que quiserem e certifique-se apenas de que a senha tenha mais de cinco caracteres.
9. Compare as senhas com dicionários e listas de bloqueio
Embora você não deva exigir senhas arbitrariamente complexas, é recomendável comparar as novas senhas com as mais conhecidas, disponíveis em dicionários públicos e listas de bloqueio. Se uma nova senha corresponder ao conteúdo dessas fontes, avise o usuário e impeça que ele a use.
Os hackers também recorrem a essas fontes de senhas para compará-las com os hashes que roubam. Portanto, verificar as senhas nessas listas dificultará ainda mais que eles descubram suas senhas em texto simples.
As práticas recomendadas para armazenar senhas são uma parte essencial do SDLC
As senhas são essenciais para sua aplicação. Armazená-las corretamente é importante a longo prazo. Dependendo da importância dos dados dos usuários, armazenar uma senha comprometida pode levar sua empresa inteira à falência.
Práticas inadequadas de gerenciamento de senhas podem causar muitos problemas de segurança: elas podem facilitar ataques externos e internos, além de deixar você vulnerável à reutilização de senhas de outros aplicativos. Se os usuários deixarem de seguir as recomendações, isso também pode gerar frustração e reduzir a adesão, aumentando os riscos de segurança. Pior ainda, pode desestimular as pessoas a usar seu serviço.
Ao desenvolver software crítico, é preciso aplicar as práticas recomendadas de segurança em todas as etapas do processo de desenvolvimento. A segurança de senhas é apenas uma pequena parte do SDLC seguro. Impeça que invasores tenham acesso às suas senhas. O scanner estático de segurança de aplicações Snyk Code verifica seu código em busca de vulnerabilidades conhecidas e mostra como corrigi-las.
Proteja suas dependências de código aberto
As ferramentas da Snyk, desenvolvidas para quem programa, criam PRs de correção com um clique para dependências de código aberto vulneráveis e suas dependências transitivas.