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):
PASSWORD_BCRYPT é usado para criar novos hashes de senha usando o algoritmo CRYPT_BLOWFISH. Isso sempre resultará em um hash usando o formato de criptografia "$ 2y $", que sempre tem 60 caracteres de largura.
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)
ou TEXT
.
Você poderia usar uma consulta SQL completa como sua senha e seria um hash, tornando-a inexecutável pelo mecanismo SQL, por exemplo,
SELECT * FROM `users`;
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:
var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));
Resultados:
string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a "dessert topping" & a <floor wax>! " // double quotes, ampersand and braces have been changed
string(65) "I'm a "dessert topping" & a <floor wax>! " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>! " // escape characters have been added
string(34) "I'm a "dessert topping" & a ! " // looks like we have something missing
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 com password_verify()
. O seguinte iria falhar:
password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query
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 .