Como devo escapar ou limpar as senhas fornecidas pelo usuário antes de hash e armazená-las em meu banco de dados?
Quando os desenvolvedores de PHP consideram hash nas senhas dos usuários para fins de segurança, eles geralmente tendem a pensar nessas senhas como fariam com quaisquer outros dados fornecidos pelo usuário. Este assunto surge frequentemente em questões de PHP relacionadas ao armazenamento de senhas; o desenvolvedor muitas vezes quer para limpar a senha usando funções como escape_string()
(em várias iterações), htmlspecialchars()
, addslashes()
e outros antes de hash-lo e armazená-lo no banco de dados.
Respostas:
Você nunca deve escapar, cortar ou usar qualquer outro mecanismo de limpeza em senhas que fará hash com PHP
password_hash()
por uma série de razões, a maior delas porque a limpeza adicional da senha requer código adicional desnecessário.Você vai argumentar (e você vê isso em todas as postagens onde os dados do usuário são aceitos para uso em seus sistemas) que devemos limpar todas as entradas do usuário e você estaria certo para todas as outras informações que estamos aceitando de nossos usuários. As senhas são diferentes. As senhas com hash não podem oferecer nenhuma ameaça de injeção de SQL porque a string é transformada em hash antes de ser armazenada no banco de dados.
O ato de hash de uma senha é o ato de tornar a senha segura para armazenar em seu banco de dados. A função hash não dá um significado especial a nenhum byte, portanto, nenhuma limpeza de sua entrada é necessária por razões de segurança
Se você seguir os mantras de permitir que os usuários usem as senhas / frases que desejam e não limitar as senhas , permitindo qualquer comprimento, qualquer número de espaços e qualquer hash de caracteres especiais tornará a senha / frase secreta segura, não importa o que esteja contido dentro a senha. A partir de agora, o hash mais comum (o padrão),
PASSWORD_BCRYPT
transforma a senha em uma string de 60 caracteres contendo um sal aleatório junto com as informações de senha em hash e um custo (o custo algorítmico de criar o hash):Os requisitos de espaço para armazenar o hash estão sujeitos a alterações à medida que diferentes métodos de hash são adicionados à função, portanto, é sempre melhor aumentar o tipo de coluna para o hash armazenado, como
VARCHAR(255)
ouTEXT
.Você poderia usar uma consulta SQL completa como sua senha e seria um hash, tornando-a inexecutável pelo mecanismo SQL, por exemplo,
Pode ser hash para
$2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G
Vamos ver como diferentes métodos de sanitização afetam a senha -
A senha é
I'm a "dessert topping" & a <floor wax>!
(há 5 espaços no final da senha que não são exibidos aqui).Quando aplicamos os seguintes métodos de corte, obtemos alguns resultados totalmente diferentes:
Resultados:
O que acontece quando os enviamos para
password_hash()
? Todos eles são hash, assim como a consulta acima. O problema surge quando você tenta verificar a senha. Se empregarmos um ou mais desses métodos, devemos reutilizá-los antes de compará-los compassword_verify()
. O seguinte iria falhar:Você teria que executar a senha postada por meio do método de limpeza escolhido antes de usar o resultado disso na verificação de senha. É um conjunto desnecessário de etapas e não tornará o hash melhor.
Usando uma versão do PHP inferior a 5.5? Você pode usar o
password_hash()
pacote de compatibilidade .Você realmente não deve usar hashes de senha MD5 .
fonte
Antes de fazer o hash da senha, você deve normalizá-la conforme descrito na seção 4 do RFC 7613 . Em particular:
e:
Isso tenta garantir que, se o usuário digitar a mesma senha, mas usando um método de entrada diferente, a senha ainda deverá ser aceita.
fonte