Wie sicher ist mein PHP-Anmeldesystem?
Ich bin neu in PHP und dies ist auch mein Erster log-in-system, so wäre es toll, wenn Jungs Sie könnten sich über meine code und sehen Sie, wenn Sie Sie vor Ort alle Sicherheitslücken:
Hinweis: ich bin Desinfektion aller Benutzereingaben obwohl es hier nicht gezeigt.
Anmelden:
Schritt 1: ich nehme das Passwort, das der Benutzer ausgewählt hat, und führen Sie es durch diese Funktion:
encrypt($user_chosen_password, $salt);
function encrypt($plain_text, $salt) {
if(!$salt) {
$salt = uniqid(rand(0, 1000000));
}
return array(
'hash' => $salt.hash('sha512', $salt.$plain_text),
'salt' => $salt
);
}
Schritt 2: ich, und speichern Sie dann den hash und den salt ($password['hash']
und $password['salt']
) in der Tabelle users in der Datenbank:
id | username | password | salt | unrelated info...
-----------------------------------------------------------
1 | bobby | 809a28377 | 809a28377f | ...
fd131e5934
180dc24e15
bbe5f8be77
371623ce36
4d5b851e46
Log-In:
Schritt 1: ich den Benutzernamen den der Benutzer eingegeben und tun Sie einen Blick auf die Datenbank, um zu sehen, wenn Zeilen zurückgegeben werden. Auf meiner Website keine 2 Benutzer teilen sich die gleiche
Benutzernamen die Benutzernamen-Feld hat immer einen eindeutigen Wert. Wenn ich 1 Zeile zurückgegeben, schnappe ich mir das Salz für diesen Benutzer.
Schritt 2: Dann Lauf ich die vom Benutzer eingegebenen Passwort durch die Funktion encrypt (wie bereits oben gepostet), aber dieses mal habe ich liefern auch den salt aus der Datenbank abgerufen werden:
encrypt($user_entered_password, $salt);
Schritt 3: ich habe nun das richtige Passwort zur Partie gegen die in dieser variable: $password['hash']
. So habe ich also eine zweite Suche in der Datenbank um zu sehen, ob die
Benutzernamen eingegeben und das gehashte Passwort zusammen, die eine einzelne Zeile zurückgeben. Wenn ja, dann werden die Anmeldeinformationen des Benutzers korrekt sind.
Schritt 4: um die Anmeldung der Benutzer, nachdem Ihre Anmeldeinformationen übergeben Generiere ich einen zufälligen eindeutigen string und hash:
$random_string = uniqid(rand(0, 1000000));
$session_key = hash('sha512', $random_string);
Ich dann legen Sie die $session_key
in die active_sessions
Tabelle in der Datenbank:
user_id | key
------------------------------------------------------------
1 | 431b5f80879068b304db1880d8b1fa7805c63dde5d3dd05a5b
Schritt 5:
Nehme ich die unverschlüsselte eindeutige Zeichenfolge erzeugt im letzten Schritt ( $random_string
), und als Wert ein cookie, das nenne ich active_session
:
setcookie('active_session', $random_string, time()+3600*48, '/');
Schritt 6:
Oben auf meiner header.php
gehören gibt es diesen check:
if(isset($_COOKIE['active_session']) && !isset($_SESSION['userinfo'])) {
get_userinfo();
}
Den get_userinfo()
Funktion führt ein lookup auf der users
Tabelle in der Datenbank und gibt ein assoziatives array zurück welche in einer session gespeichert genannt userinfo
:
//zuerst diese Funktion nimmt den Wert der active_session cookie-hashes, um die session_key:
hash('sha512', $random_string);
//dann es macht einen lookup auf die active_sessions
Tabelle, um zu sehen, wenn ein Datensatz durch diese key
existiert, wenn ja wird es greifen die user_id
zugeordnet, speichern und verwenden, und dies für eine zweite Suche auf dem users
Tabelle, um die userinfo
:
$_SESSION['userinfo'] = array(
'user_id' => $row->user_id,
'username' => $row->username,
'dob' => $row->dob,
'country' => $row->country,
'city' => $row->city,
'zip' => $row->zip,
'email' => $row->email,
'avatar' => $row->avatar,
'account_status' => $row->account_status,
'timestamp' => $row->timestamp,
);
Wenn die userinfo
session existiert ich weiß der Benutzer authentifiziert ist. Wenn es nicht existiert, aber die active_session
cookie vorhanden ist, dann Sie, dass der check
an der Spitze der header.php
- Datei erstellen, die in dieser Sitzung.
Der Grund, warum ich bin mit einem cookie und Sitzungen nicht allein zum speichern des login. Also, wenn der Benutzer den browser schließt die Sitzung gegangen, aber die
cookie noch vorhanden ist. Und da ist Sie, dass der check an der Spitze der header.php
, die Sitzung wird wieder hergestellt und der Benutzer kann die Funktion als angemeldeter
im Benutzer-als normal.
Abmelden:
Schritt 1: Sowohl die userinfo
Sitzung und die active_session
Cookies werden nicht gesetzt.
Schritt 2: Den zugehörigen Datensatz aus der active_sessions
Tabelle in der Datenbank entfernt wird.
Hinweise: Das einzige Problem, das ich sehen kann (und vielleicht gibt es viele andere), ist, wenn der Benutzer fakes, die active_session
cookie, indem Sie es erstellen sich in Ihrem browser. Natürlich müssen Sie festlegen, wie die cookie-Wert einen string, nach dem es verschlüsselt ist, muss mit einem Datensatz in der active_sessions
Tabelle aus, wo ich das abrufen der user_id
zu erstellen, die in dieser Sitzung. Ich bin mir nicht sicher, was die Chancen dieser ist realistisch, für einen Benutzer (vielleicht mit ein automatisiertes Programm) zu erraten, die eine Zeichenfolge korrekt, was Sie nicht wissen, werden dann sha512 verschlüsselt und abgeglichen werden der string in der active_sessions
Tabelle in der Datenbank, um Benutzer-id zu erstellen, die in dieser Sitzung.
Sorry für den großen Aufsatz, aber da dies so ein wichtiger Teil von meiner Website und aufgrund meiner Unerfahrenheit wollte ich nur führen Sie es von einem erfahrenen Entwickler, um sicherzustellen, dass es ist tatsächlich sicher.
So sehen Sie alle Sicherheitslücken in dieser Strecke, und wie kann es verbessert werden?
mt_rand()
statt rand()
InformationsquelleAutor der Frage TK123 | 2011-12-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie auch eine Art timeout oder failover zu verhindern, dass gegen brute-force-Angriffe. Es gibt eine Reihe von Möglichkeiten, dies zu tun, einschließlich IP-basierte Sperrung, inkrementelle timeouts, etc. Keiner von beiden wird jemals stop ein hacker, aber Sie können es sehr viel schwieriger.
Anderer Stelle (die du noch nicht erwähnt habe, ich weiß also nicht, Ihren plan) Ausfall-Nachrichten. Stellen Sie Fehlermeldungen wie vage wie möglich. Die Bereitstellung einer Fehlermeldung wie "Benutzername existiert, aber die Passwörter nicht übereinstimmen', die hilfreich sein könnten, um den end-Benutzer, aber es tötet login-Funktionalität. Sie nur konvertiert eine brute-force-Angriff, das sollte
O(n^2)
Zeit zuO(n)
+O(n)
. Stattdessen musste versuchen, jede permutation in einer rainbow-Tabelle (zum Beispiel), der hacker, der gerade versucht, alle Werte für Benutzername (mit ein Passwort gesetzt), bis die Fehlermeldung ändert sich. Dann, es weiß einen gültigen Benutzer, und nur um die brute-force das Passwort.Entlang dieser Linien, Sie sollten auch sicherstellen, dass die gleiche Menge an Zeit, die verstreicht, wenn ein Benutzername existiert und existiert nicht. Sie laufen weitere Verfahren, wenn ein Benutzername tatsächlich existiert. Als solche, die Reaktion wäre die Zeit länger, wenn ein Benutzername existiert, vs, wenn es nicht funktioniert. Eine unglaublich geschickte hacker könnten die Zeit, die Seite-Anfragen zu finden, die einen gültigen Benutzernamen ein.
Ebenso sollten Sie sicherstellen, dass zusätzlich zu den auslaufenden cookies, Sie verfallen auch die sessions-Tabelle.
Schließlich in die
get_user_info()
aufrufen, sollten Sie beenden alle offenen Sitzungen, wenn es mehrere gleichzeitige, aktive logins. Stellen Sie sicher, timeout sessions nach einer gewissen Inaktivität (30 Minuten).Entlang der Linien von dem, was @Greg Hewgill erwähnt, haben Sie nicht enthalten jede der folgenden:
Du server ist sicher, aber es spielt keine Rolle, wie schrecklich sichern Sie sich Ihren Algorithmus ist, wenn jemand die Daten Lesen kann, der ist ausgetauscht (MITM). Sie sollten sicherstellen, dass Sie nur die Kommunikation über ein verschlüsseltes Protokoll.
InformationsquelleAutor der Antwort sethvargo
Also, wie funktioniert der Passwort vom browser an den server? Sie habe nicht erwähnt, Schutz gegen man-in-the-middle-Angriffe.
InformationsquelleAutor der Antwort Greg Hewgill
Sieht es aus wie der code, den Sie erstellt haben, nicht prüfbar durch automatische unit-und integration-tests. Das macht es schwierig, vor Ort alle Fehler, die eventuell aufgenommen werden in Ihrer Umsetzung im Laufe der Zeit und während der Ausführung in einer Produktionsumgebung.
Diese Regel führt zu Sicherheitsproblemen, da die Sicherheit eine sehr strenge und korrekte Ausführung und vernünftiger Umgang mit den Daten ist nicht getestet/überprüft.
(Es ist nur ein weiterer Punkt auf der Liste, siehe auch die Antwort auf die Frage, wie sicher der transport layer, auch Sie haben nicht angegeben, wie Sie schützen Ihre session-Daten vor Manipulationen.)
InformationsquelleAutor der Antwort hakre
Dieser code...
...ist schlecht. Verwenden Sie das neue Passwort-API und mit ihm getan werden. Es sei denn, Sie ein Experte sind, sollten Sie nicht versuchen, Sie zu entwerfen Ihr eigenes Authentifizierungssystem. Sie sind extrem schwer zu bekommen Recht.
Nur lassen Sie PHP-Griff-session-management.
rand()
undmt_rand()
sind beide sehr unsichere Zufallszahl-Generatoren.InformationsquelleAutor der Antwort Scott Arciszewski
Sollten Sie verwenden, mt_rand() anstelle von rand()
Ist hier, warum:
InformationsquelleAutor der Antwort Lucas Bustamante