Przechowywanie haseł¶
Hasła użytkowników należą do najwrażliwszych danych, jakie przechowuje system. Ich ochrona opiera się na zasadzie, która nie zawsze jest oczywista: żeby przy logowaniu sprawdzić, czy użytkownik podał właściwe hasło, system wcale nie musi go znać. Wystarczy, że zapisze je w postaci, która nie pozwala odczytać samego hasła, ale pozwala potwierdzić, że podano to właściwe.
Służy do tego skrót hasła, czyli wynik jednokierunkowego przekształcenia. Przy zakładaniu konta system oblicza skrót z podanego hasła i zapamiętuje wyłącznie ten wynik. Przy każdym kolejnym logowaniu powtarza to samo obliczenie i porównuje oba wyniki. Ich zgodność oznacza, że hasło jest poprawne. Działanie odwrotne, czyli wyznaczenie hasła na podstawie samego skrótu, nie jest możliwe.
O podatności mówimy wtedy, gdy ta zasada zostaje naruszona i hasła można odczytać z bazy danych. Dzieje się tak, gdy zapisano je jawnie, zabezpieczono w sposób odwracalny albo użyto algorytmu, który nie został do tego celu zaprojektowany.
System należy projektować tak, aby potencjalny wyciek bazy danych nie pozwalał na poznanie haseł użytkowników. Skutki takiego wycieku wykraczają najczęściej poza jeden system - użytkownicy powszechnie stosują to samo hasło w wielu miejscach. Atakujący, który pozna hasło z jednego systemu, spróbuje więc zalogować się nim do poczty, bankowości czy systemów firmowych ofiary.
Skutki udanego ataku¶
Nieodpowiednie przechowywanie haseł może prowadzić do:
- ujawnienia haseł użytkowników po wycieku bazy danych,
- przejęcia kont w serwisach, w których użytkownicy użyli tego samego hasła,
- przejęcia kont administracyjnych i uzyskania pełnej kontroli nad systemem,
- utrzymania dostępu przez atakującego długo po incydencie,
- konsekwencji prawnych i wizerunkowych organizacji.
Typowe scenariusze¶
Hasła przechowywane w formie jawnej¶
Zapis hasła w formie zwykłego tekstu lub zaszyfrowanego algorytmem odwracalnym oznacza, że każdy, kto uzyska dostęp do bazy, a w drugim przypadku również do klucza, od razu dysponuje kompletem haseł. Poprawnie zbudowany system nie zna haseł swoich użytkowników i nie potrafi przypomnieć dotychczasowego hasła, a jedynie umożliwić ustawienie nowego.
Użycie szybkich funkcji skrótu¶
Algorytmy takie jak MD5, SHA1 czy SHA256 zostały zaprojektowane tak, aby działać jak najszybciej. To zaleta przy sumach kontrolnych i wada przy hasłach, ponieważ atakujący liczy miliardy skrótów na sekundę na powszechnie dostępnym sprzęcie. W teście wewnętrznym CERT Polska typowe hasła użytkowników zabezpieczone algorytmem SHA1 zostały złamane w czasie poniżej 5 minut. Do haseł należy stosować funkcje celowo powolne i kosztowne pamięciowo.
Brak losowej soli¶
Sól to unikalna, losowa wartość dopisywana do każdego hasła przed obliczeniem skrótu. Jej brak powoduje, że identyczne hasła dwóch użytkowników mają identyczne skróty. Dzięki temu atakujący jest w stanie stwierdzić które konta korzystają z tego samego hasła, a złamanie jednego skrótu daje mu dostęp do pozostałych kont. Bez soli może też skorzystać z gotowych, wcześniej wyliczonych tablic skrótów.
Własne, autorskie konstrukcje¶
Zdarza się, że zamiast algorytmu przeznaczonego do haseł stosuje się rozwiązanie utworzone samodzielnie np.: łączenie kilku funkcji skrótu, mieszanie hasła ze stałym ciągiem znaków, czy przestawianie znaków. Taka procedura sprawia wrażenie skomplikowanej, a przez to bezpiecznej, ale osobie bez doświadczenia w kryptografii trudno ocenić, czy stworzone rozwiązania rzeczywiście odpowiednio chronią hasło. Typowe błędy tego rodzaju są poważne: wynik bywa możliwy do odwrócenia lub zbiór możliwych wyników jest na tyle mały, że różne hasła prowadzą do tego samego skrótu - w takiej sytuacji atakujący może zweryfikować je wszystkie.
Brak możliwości zmiany parametrów w czasie¶
Z roku na rok zwiększa się moc obliczeniowa dostępnych na rynku urządzeń. Parametry zabezpieczenia haseł, które były akceptowalne kilka lat temu, dziś mogą już być niewystarczające. System, który nie przewiduje możliwości zwiększenia kosztu obliczeniowego ani migracji istniejących skrótów, starzeje się w sposób niewidoczny dla administratora.
Ujawnianie haseł poza bazą danych¶
Hasła mogą trafić do logów aplikacji, komunikatów o błędach, systemów monitoringu, parametrów adresów URL, kopii zapasowych czy wiadomości e-mail wysyłanych przy zakładaniu konta. Prawidłowe zabezpieczenie hasła w bazie danych nie ma wtedy znaczenia, bo jest ono i tak dostępne w innym, zwykle słabiej chronionym miejscu.
Rekomendacje¶
Aby ograniczyć ryzyko występowania podatności należy:
- Przechowywać wyłącznie nieodwracalny skrót hasła, obliczony przy użyciu algorytmu przeznaczonego do haseł: Argon2, Bcrypt, Scrypt lub PBKDF2,
- Stosować unikalną, losową sól dla każdego hasła, generowaną przez kryptograficznie bezpieczny generator liczb losowych,
- Dobrać parametry kosztu obliczeniowego do posiadanego sprzętu i okresowo je weryfikować,
- Nie stosować do haseł zwykłych funkcji skrótu, takich jak MD5, SHA1 czy SHA256, ani własnych konstrukcji,
- Przewidzieć mechanizm migracji istniejących skrótów na nowszy algorytm lub wyższe parametry,
- Nie zapisywać haseł w logach, komunikatach o błędach, systemach monitoringu ani w adresach URL.
Punkt wyjścia dla parametrów
Poniższe wartości są typowym, powszechnie przyjmowanym minimum. Docelowe parametry należy dobrać eksperymentalnie tak, aby weryfikacja jednego hasła trwała rzędu kilkuset milisekund na produkcyjnym sprzęcie, i przeglądać je co jakiś czas.
| Algorytm | Przykładowe parametry wyjściowe |
|---|---|
| Argon2id | 19 MiB pamięci, 2 iteracje, równoległość 1 |
| Bcrypt | koszt (work factor) co najmniej 10 |
| Scrypt | N = 2^17, r = 8, p = 1 |
| PBKDF2-HMAC-SHA256 | co najmniej 600 000 iteracji |
Zalecanym domyślnym wyborem dla nowych systemów jest Argon2id. PBKDF2 warto wybierać przede wszystkim tam, gdzie wymagana jest zgodność z formalnymi standardami lub certyfikowanymi modułami kryptograficznymi.
Bcrypt i długie hasła
Bcrypt obsługuje maksymalnie 72 bajty danych wejściowych, co przy niektórych kodowaniach oznacza mniej niż 64 znaki. Dłuższe hasła są po cichu obcinane. Rozwiązaniem stosowanym w praktyce jest wstępne obliczenie skrótu hasła innym bezpiecznym algorytmem i podanie wyniku na wejście Bcrypta. Implementacja musi być jednak wykonana starannie, ponieważ błędne wstępne hashowanie umożliwia atak typu password shucking, czyli całkowite obejście warstwy Bcrypta.
Migracja istniejących haseł
Skrótów zabezpieczonych słabym algorytmem nie da się przeliczyć bez znajomości haseł. Stosuje się dwa podejścia. Pierwsze polega na ponownym obliczeniu skrótu prawidłowym algorytmem przy najbliższym poprawnym logowaniu użytkownika, przy jednoczesnym oznaczeniu rekordu w bazie. Drugie, stosowane po incydencie lub gdy dotychczasowe zabezpieczenie było wyraźnie niewystarczające, polega na unieważnieniu wszystkich haseł i wymuszeniu ich zmiany. Konta nieaktywne, które nie zalogują się w wyznaczonym czasie, warto objąć drugim podejściem.
Korzystaj z gotowych implementacji
Zabezpieczeń haseł nie powinno się budować samodzielnie. Popularne języki i frameworki udostępniają gotowe funkcje, które dobierają algorytm, generują sól i zapisują ją razem ze skrótem, a przy weryfikacji odczytują wszystkie potrzebne parametry. W PHP są to password_hash i password_verify. Analogiczne mechanizmy oferują pozostałe popularne języki oraz frameworki webowe.
Zasady dotyczące wymagań stawianych użytkownikom opisano w osobnym artykule: Polityka haseł.