2013-01-02 6 views
11

Jestem w trakcie kodowania formularza logowania "zapamiętaj mnie", a do tej pory samouczki, które przeczytałem (częściowo w celu upewnienia się, że robię to dobrze) wszyscy mówią, że przechowują zaszyfrowane hasło w cookie wraz z nazwą użytkownika. Następnie za każdym razem, gdy PHP sprawdza, czy bieżący użytkownik nie jest zalogowany, sprawdź pliki cookie i poszukaj tych wartości. Jeśli nazwa użytkownika pasuje do hasła, jesteś w.Wada bezpieczeństwa "Remember Me" w języku PHP?

Dla mnie jest to luka w dziale bezpieczeństwa. Gdyby ktoś włamał się do bazy danych lub w jakiś sposób uzyskał dostęp do zaszyfrowanych haseł, nie musiałby ich nawet łamać. Po prostu ustaw własne ciasteczka i idź. Czy mam rację, czy po prostu paranoję?

Mój system logowania wykorzystuje sesje do śledzenia bieżącego identyfikatora użytkownika oraz 1/0 dla szybkiego zalogowania/wylogowania. Użytkownik nie może edytować sesji AFAIK, więc jest to bezpieczne (jeśli tak nie jest, proszę dać mi znać). Myślałem o przechowywaniu identyfikatora sesji w pliku cookie, aby później go wznowić, ale to też nie jest bezpieczne.

Bardzo zależy mi na bezpieczeństwie moich użytkowników, w jaki sposób mogę właściwie chronić ich dane, zachowując jednocześnie funkcjonującą stronę internetową?

+0

Nie będę przechowywać zaszyfrowanego hasła, tylko identyfikator użytkownika w pliku cookie, który wygasa za X dni. W przypadku obszarów "wrażliwych" (na przykład zarządzanie kontem/profilem) można wymagać od nich logowania, jeśli nie mają one prawidłowej wartości $ _SESSION (którą należy ustawić podczas logowania). – JennyDanger

+1

W jaki sposób przechowujesz obecnie identyfikator sesji, jeśli zapisanie jej w pliku cookie jest "niezabezpieczone?" –

+0

@georgefox obecnie, nie przechowuję identyfikatora sesji w czymkolwiek, tylko mówiłem, że jest to możliwość funkcji zapamiętaj mnie. – Scott

Odpowiedz

11

Zazwyczaj, gdy serwer jest proszony o pamiętać użytkownikowi, wydaje dodatkowy plik cookie obok normalny cookie sesji, a ten nowy ciąg zawiera nazwę użytkownika i odpowiednią ilość losowych znaków, które sprawiają, że unguessable. Jest to oczywiście zapisane w bazie danych (ze względów bezpieczeństwa możesz chcieć traktować go jak hasło, a tym samym solić i mieszać) i następnym razem, gdy użytkownik łączy się z tą samą przeglądarką (zakładając, że poprzednia sesja wygasła), aplikacja otrzymuje losowy ciąg, sprawdza bazę danych, a jeśli jest dopasowanie, użytkownik jest uwierzytelniany.

Alternatywą jest przeniesienie czasu wygaśnięcia sesji przed pewną kwotą.

Jakie są luki w zabezpieczeniach? Jeśli korzystasz z dobrego generatora losowego, jedyną rzeczą, która może się stać, jest to, że użytkownik uzyskuje dostęp do aplikacji ze współużytkowanej przeglądarki i nie wylogowuje się ręcznie po jej zakończeniu.

The normalnych zasad zawsze stosować skoro jesteś na niezabezpieczonym kanałem: stosować HTTPS, w przeciwnym razie, kto siedzi w między komputerem a serwerem może ukraść ciasteczka (albo sesja jeden lub pamiętać-me jeden) i zachowywać się tak, jakby to był ty.

Bonus, this must-read by Jeff Atwood

+0

To wydaje się być dobrym pomysłem, dzięki! Ponadto, czytając ten wpis logowania potwora teraz! – Scott

-3

Znalazłem ten sam problem podczas pracy nad moją własną stroną internetową, najlepszym sposobem, jaki znalazłem, było po prostu zapamiętywanie haseł, tylko nazw użytkowników, zapewniając szybsze logowanie, ale nie mniej bezpieczne. Faktem jest, że nie ma pewności co do sposobu, w jaki będą one całkowicie bezpieczne. Poza tym w nowych przeglądarkach użytkownik może zapamiętać swoją przeglądarkę.

Ale jeśli trzeba mieć zapisane hasła, spróbuj tego:

mieć wiele plików cookie, 2 byłoby najprostszym i użyć jednego z zaszyfrowanym hasłem, a druga odbyła się klucz szyfrowania. Hasło w bazie danych będzie zawierało kolejne zaszyfrowane hasło, uzyskane przy użyciu zapisanych kluczy szyfrowania. Kiedy będziesz gotowy do sprawdzenia hasła, wyodrębnij wartości i zaszyfruj hasło.

Mam nadzieję, że to było pomocne. Powodzenia!

Edycja: Mogłem źle to zrozumieć, jeśli użytkownik jest wciąż zalogowany, dobrą praktyką jest przechowywanie zmiennej sesji.

+1

Nigdy nie zapisuj hasła w żaden sposób (zaszyfrowane hasło, które może być używane do logowania to nadal hasło) na kliencie. Zapisz tylko klucz zapisany na serwerze. Klucze te można później odwołać, ale zaszyfrowane hasło będzie obowiązywać do czasu zmiany. –

+0

To niekoniecznie jest prawdą, ponieważ można ustawić datę wygaśnięcia; jednak wolałbym nie używać mojej drugiej metody. – Zero

0

Jeśli chcesz go zabezpieczyć, nie pozwalają użytkownikom przechowywać je zalogowany.

Podczas ustawiania sesji, upewnij się, aby związać ipaddress do identyfikatora sesji, tak, że jeśli ktoś wybiera do sesji później, można to zrobić tylko z tego samego adresu IP. Yo można to zrobić, prowadząc bazę danych z (zakodowanymi) identyfikatorami sesji i hashedressami. Używam funkcji phps http://php.net/manual/en/class.sessionhandler.php, aby ustawić obsługę sesji i dopasować sesje za pomocą ipaddresses.

+1

Adresy IP nie są przeznaczone do ochrony i nie można ufać adresom IP. Sprawdzanie adresu IP, jak zauważysz, nadal jednak utrudnia życie złym ludziom. –

2

Nigdy nie zapisuj haseł w jakikolwiek sposób (zaszyfrowane hasło, które może być używane do logowania to nadal hasło) na kliencie.

Użyj losowo wygenerowanego klucza, bezpiecznie przechowywanego na serwerze. Te klucze mogą zostać później odwołane w przeciwieństwie do zaszyfrowanych haseł, które będą obowiązywać do czasu ich zmiany.

Za pomocą php można wygenerować losowy klucz podobny do tego md5(uniqid(mt_rand(), true)). Dla lepszego bezpieczeństwa przechowywać solone i mieszane w db.

Przykład tabeli:

login_keys (
    user_id int, 
    key char(40), # sha1 
    salt char(15) 
) 

pamiętać również należy włączyć HTTP tylko Cookie opcję.

Powiązane problemy