Desejo reescrever meus scripts de login nos sites dos clientes para torná-los mais seguros. Quero saber quais as melhores práticas que posso implementar nisso. Os painéis de controle protegidos por senha estão em abundância, mas poucos parecem implementar as práticas recomendadas em termos de código, velocidade e segurança.
Eu vou estar usando PHP e um banco de dados MYSQL.
Eu costumava usar o md5, mas vejo que sha256 ou sha512 seria melhor (junto com hash e sal seguros).
Alguns scripts de logon registram o endereço IP durante toda a sessão ou até o agente do usuário, mas quero evitar isso, pois não é compatível com servidores proxy.
Também estou um pouco por trás da melhor prática no uso de sessões no PHP 5 (a última vez que li foi o PHP 4), portanto, algumas práticas recomendadas com isso seriam úteis.
Obrigado.
fonte
Respostas:
O melhor é não reinventar a roda. Mas, eu entendo, no mundo PHP, pode ser difícil encontrar um componente de alta qualidade que já faça isso (mesmo que eu tenha certeza de que as estruturas implementam essas coisas e suas implementações já foram testadas, sólidas, revisadas por código etc.) )
Se, por alguns motivos, você não puder usar uma estrutura, veja algumas sugestões:
Sugestões relacionadas à segurança
Use PBKDF2 ou Bcrypt, se puder . Está feito para isso.
Fundamentação da petição: ambos os algoritmos podem tornar o processo de hash arbitrariamente lento, exatamente o que você deseja ao fazer o hash de senhas (alternativas mais rápidas significam uma força bruta mais fácil). Idealmente, você deve ajustar os parâmetros para que o processo se torne cada vez mais lento no mesmo hardware, enquanto um hardware novo e mais rápido é lançado.
Se não puder, pelo menos não use MD5 / SHA1. Nunca. Esqueça . Use SHA512, por exemplo. Use sal também.
Justificativa: MD5 e SHA1 são muito rápidos. Se o invasor tiver acesso ao seu banco de dados contendo os hashes e possuir uma máquina (nem mesmo particularmente) poderosa, forçar brutalmente uma senha será rápido e fácil. Se não houver sais, as chances de o invasor encontrar a senha real aumentam (o que pode causar danos adicionais se a senha for reutilizada em outro lugar).
No PHP 5.5.0 e posterior, use
password_hash
epassword_verify
.Justificativa: chamar uma função fornecida pela estrutura é fácil, portanto, o risco de cometer um erro é reduzido. Com essas duas funções, você não precisa pensar em parâmetros diferentes, como o hash. A primeira função retorna uma única string que pode ser armazenada no banco de dados. A segunda função usa essa sequência para verificação de senha.
Proteja-se da força bruta . Se o usuário enviar uma senha errada quando já tiver enviado outra senha errada há 0,01 segundos, é um bom motivo para bloqueá-la. Embora os seres humanos possam digitar rápido, eles provavelmente não podem ser tão rápidos.
Outra proteção seria definir um limite de falhas por hora. Se o usuário enviou 3600 senhas erradas em uma hora, uma senha por segundo, é difícil acreditar que seja um usuário legítimo.
Fundamentação da petição: se suas senhas são divididas de maneira insegura, a força bruta pode ser muito eficaz. Se as senhas forem armazenadas com segurança, a força bruta ainda estará desperdiçando os recursos e a largura de banda da rede do servidor, causando desempenho inferior para usuários legítimos. A detecção de força bruta não é fácil de desenvolver e acertar, mas para qualquer sistema, exceto o minúsculo, vale totalmente a pena.
Não peça aos usuários que alterem suas senhas a cada quatro semanas. Isso é extremamente irritante e diminui a segurança, pois incentiva a segurança baseada em post-it.
Fundamentação da petição: a ideia de que forçar a alteração de senhas a cada n semanas protege o sistema da força bruta está errada. Os ataques de força bruta geralmente são bem-sucedidos em segundos, minutos, horas ou dias, o que torna irrelevantes as alterações mensais da senha. Por outro lado, os usuários são ruins em lembrar senhas. Além disso, se eles precisarem alterá-los, eles tentarão usar senhas muito simples ou apenas anotarão suas senhas em post-its.
Audite tudo, sempre. Armazene logons, mas nunca armazene senhas no log de auditoria. Verifique se o log de auditoria não pode ser modificado (ou seja, você pode adicionar dados no final, mas não modificar os dados existentes). Verifique se os logs de auditoria estão sujeitos a backup regular. Idealmente, os logs devem ser armazenados em um servidor dedicado com acessos muito restritivos: se outro servidor for invadido, o invasor não poderá apagar os logs para ocultar sua presença (e o caminho percorrido durante o ataque).
Não lembre-se da credencial do usuário nos cookies, a menos que o usuário peça para fazê-lo (a caixa de seleção "Lembrar-me" deve estar desmarcada por padrão para evitar erros humanos).
Sugestões de facilidade de uso
<span/>
. Os navegadores não podem preencher o campo de senha nesse caso (pelo menos o Firefox não pode fazer isso), portanto, força o logoff e o logon com um formulário comum preenchido pelo navegador.fonte
bcrypt
é feito por pessoas altamente qualificadas. Também é testado, revisado, etc. Portanto, não há razão para implementar a mesma coisa. É como criar seu próprio algoritmo de criptografia para o seu site. * "Por que não md5 / sha1?": Veja por exemplo en.wikipedia.org/wiki/MD5#Securitybcrypt
se possível. Caso contrário, use algum outro tipo de hash iterado.mysql_real_escape_string
. Nunca use concatenação de strings para criar sua consulta. Use consultas preparadas e parametrizadas. A maioria, se não todos, os drivers de banco de dados para PHP é compatível. Se você não sabe como fazê-lo, passar algum tempo aprendendo comoprepare
,bind
eexecute
usando qualquer DB que você está usando. É a única maneira de se proteger contra a injeção de SQL. A DOP suporta isso.fonte
mysql_real_escape_string
é falsa segurança - não é uma garantia. Consultas parametrizadas são.Use um hash salgado de mão única (de preferência o SHA512 usando http://au2.php.net/manual/en/function.hash.php ) ... dessa maneira, se alguém hackear seu banco de dados, mesmo que conheça o sal , eles não podem extrair as senhas (sem uma tabela arco-íris, que seria muito longa para o SHA512).
Use HTTPS.
Não envie confirmações de nome de usuário / senha por e-mail de volta ao usuário quando ele se registrar.
Se você permitir cookies para 'lembrar de mim' - adicione um login extra para acessar as funções de administração e edição de perfil.
Se um usuário errar uma senha, não diga que a senha está errada (digamos que sempre tenha o 'nome de usuário ou senha errado') - dessa forma, menos pistas sobre o que são nomes de usuário válidos.
Tente implementar o nome de tela e o login - dessa forma, menos usuários exibirão seu nome de login nas listas de usuários.
fonte
fonte
Aqui está um conselho: verifique se seus cookies não podem ser acessados com JS para evitar roubo, consulte Protegendo seus cookies: artigo HttpOnly por Jeff Atwood
fonte