Jak uciec od haseł podanych przez użytkownika lub je wyczyścić, zanim je zaszyfuję i zapiszę w mojej bazie danych?
Kiedy programiści PHP rozważają haszowanie haseł użytkowników ze względów bezpieczeństwa, często myślą o tych hasłach tak, jak o innych danych dostarczonych przez użytkownika. Temat ten pojawia się często w pytaniach PHP związanych z przechowywaniem haseł; programista często chce oczyścić hasło przy użyciu funkcji takich jak escape_string()
(w różnych iteracji) htmlspecialchars()
, addslashes()
a inni go przed mieszania i przechowywania go w bazie danych.
Odpowiedzi:
Nigdy nie powinieneś uciekać, przycinać ani używać żadnego innego mechanizmu czyszczenia haseł, które będziesz haszować z PHP z
password_hash()
wielu powodów, z których największym jest to, że dodatkowe czyszczenie hasła wymaga niepotrzebnego dodatkowego kodu.Będziesz argumentował (i widzisz to w każdym poście, w którym dane użytkownika są akceptowane do wykorzystania w twoich systemach), że powinniśmy wyczyścić wszystkie dane wejściowe użytkownika i miałbyś rację w przypadku każdej innej informacji, którą akceptujemy od naszych użytkowników. Hasła są różne. Hasła haszowane nie mogą stwarzać żadnego zagrożenia iniekcją SQL, ponieważ ciąg znaków jest zamieniany na hash przed zapisaniem w bazie danych.
Haszowanie hasła to czynność polegająca na zabezpieczeniu hasła podczas przechowywania w bazie danych. Funkcja skrótu nie nadaje specjalnego znaczenia żadnym bajtom, więc ze względów bezpieczeństwa nie jest wymagane czyszczenie jej danych wejściowych
Jeśli podążasz za mantrami pozwalającymi użytkownikom na używanie haseł / fraz, których pragną, i nie ograniczasz haseł , zezwalając na dowolną długość, dowolną liczbę spacji i haszowanie znaków specjalnych, sprawi, że hasło / hasło będzie bezpieczne bez względu na to, co jest w nim zawarte hasło. Obecnie najpopularniejszy hash (domyślny)
PASSWORD_BCRYPT
zamienia hasło w ciąg o szerokości 60 znaków zawierający losową sól wraz z zaszyfrowanymi informacjami o haśle i kosztem (algorytmicznym kosztem utworzenia skrótu):Wymagania dotyczące miejsca do przechowywania skrótu mogą ulec zmianie, ponieważ do funkcji dodawane są różne metody haszowania, dlatego zawsze lepiej jest zwiększyć typ kolumny dla przechowywanego skrótu, na przykład
VARCHAR(255)
lubTEXT
.Możesz użyć pełnego zapytania SQL jako hasła i zostanie ono zaszyfrowane, co uniemożliwi jego wykonanie przez silnik SQL, np.
Może być hashowany
$2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G
Zobaczmy, jak różne metody odkażania wpływają na hasło -
Hasło to
I'm a "dessert topping" & a <floor wax>!
(na końcu hasła jest 5 spacji, które nie są tutaj wyświetlane).Kiedy stosujemy następujące metody przycinania, uzyskujemy różne wyniki:
Wyniki:
Co się stanie, gdy wyślemy je do
password_hash()
? Wszystkie są zaszyfrowane, tak jak w przypadku powyższego zapytania. Problem pojawia się, gdy próbujesz zweryfikować hasło. Jeśli zastosujemy jedną lub więcej z tych metod, musimy je ponownie zastosować przed ich porównaniempassword_verify()
. Poniższe zawiodłyby:Będziesz musiał uruchomić przesłane hasło za pomocą wybranej metody czyszczenia, zanim użyjesz wyniku tego do weryfikacji hasła. Jest to niepotrzebny zestaw kroków i nie sprawi, że hash nie będzie lepszy.
Używasz wersji PHP mniejszej niż 5.5? Możesz użyć
password_hash()
pakietu zgodności .Naprawdę nie powinieneś używać skrótów haseł MD5 .
źródło
Przed zahaszowaniem hasła należy je znormalizować zgodnie z opisem w sekcji 4 dokumentu RFC 7613 . W szczególności:
i:
Ma to na celu zapewnienie, że jeśli użytkownik wpisze to samo hasło, ale użyje innej metody wprowadzania, hasło nadal będzie akceptowane.
źródło