Hallo liebe php.de-Community,
aktuell arbeite ich an einem "Eingeloggt bleiben"-System. Soweit funktioniert das auch, allerdings ist mir jetzt eine Sicherheitslücke aufgefallen.
Ablauf: Ein Hash wird in der Nutzerdatenbank gespeichert. Durch diesen wird später identifiziert, ob der Nutzer bereits eingeloggt war. Sollte ein Nutzer sich nun über das Loginformular einloggen und die "Angemeldet bleiben"-Checkbox aktivieren wird, falls noch nicht im Datensatz, ein Hash in die Datenbank geschrieben. Falls ein Hash dem Nutzer bereits zugewiesen war, wird dieser aus der Datenbank genommen und bei beiden Wegen als Cookie auf dem Rechner gespeichert. Bei einem Besuch des Loginbereiches wird dann geprüft, ob ein "Eingeloggt bleiben"-Cookie gesetzt ist. Wenn ja, wird in der Nutzerdatenbank nach diesem Hash, welcher in dem Cookie steht, gesucht. Falls gefunden, wird der Nutzer durch den Cookie eingeloggt.
Problem: Sollte ein Fremder Zugriff auf die Cookies eines "Angemeldet bleiben"-Nutzers erhalten, dann kann dieser den Hash in dem Cookie kopieren und in seinem Browser speichern (gibt z.B. Cookie-AddOns zum Ändern und Hinzufügen von Cookies). Besucht dieser dann die betreffende Webseite/Loginbereich, dann wird dieser einfach eingeloggt, obwohl er nicht der Besitzer des Accounts ist und sich auch noch nie mit Kennwort + Nutzername eingeloggt hat.
Meine Frage: Wie sollte das Script erweitert werden, um zu erreichen, dass diese Sicherheitslücke geschlossen wird? Das muss man irgendwie nochmal extra validieren können. Hat jemand eine Idee, wie ich das machen könnte?
StayLoggedIn im Formular
Prüfung im Nutzerbereich
aktuell arbeite ich an einem "Eingeloggt bleiben"-System. Soweit funktioniert das auch, allerdings ist mir jetzt eine Sicherheitslücke aufgefallen.
Ablauf: Ein Hash wird in der Nutzerdatenbank gespeichert. Durch diesen wird später identifiziert, ob der Nutzer bereits eingeloggt war. Sollte ein Nutzer sich nun über das Loginformular einloggen und die "Angemeldet bleiben"-Checkbox aktivieren wird, falls noch nicht im Datensatz, ein Hash in die Datenbank geschrieben. Falls ein Hash dem Nutzer bereits zugewiesen war, wird dieser aus der Datenbank genommen und bei beiden Wegen als Cookie auf dem Rechner gespeichert. Bei einem Besuch des Loginbereiches wird dann geprüft, ob ein "Eingeloggt bleiben"-Cookie gesetzt ist. Wenn ja, wird in der Nutzerdatenbank nach diesem Hash, welcher in dem Cookie steht, gesucht. Falls gefunden, wird der Nutzer durch den Cookie eingeloggt.
Problem: Sollte ein Fremder Zugriff auf die Cookies eines "Angemeldet bleiben"-Nutzers erhalten, dann kann dieser den Hash in dem Cookie kopieren und in seinem Browser speichern (gibt z.B. Cookie-AddOns zum Ändern und Hinzufügen von Cookies). Besucht dieser dann die betreffende Webseite/Loginbereich, dann wird dieser einfach eingeloggt, obwohl er nicht der Besitzer des Accounts ist und sich auch noch nie mit Kennwort + Nutzername eingeloggt hat.
Meine Frage: Wie sollte das Script erweitert werden, um zu erreichen, dass diese Sicherheitslücke geschlossen wird? Das muss man irgendwie nochmal extra validieren können. Hat jemand eine Idee, wie ich das machen könnte?
StayLoggedIn im Formular
PHP-Code:
[...]
$id = $_SESSION['id'];
if (isset($_POST['stayloggedin'])){
// Die SESSION ist bereits durch das Einloggen zugewiesen > $id
$statement = $pdo->prepare("SELECT * FROM nutzer WHERE id = '$id'");
$result = $statement->execute(array('stayloggedin'));
$slidata = $statement->fetch();
$db_stayloggedin = $slidata['stayloggedin'];
// Falls noch kein Hash in dem Datensatz "stayloggedin" des Nutzers
if ($db_stayloggedin === '') {
// Zufällige Zeichenfolge
$zufallcode = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
// ... wird als Cookie gesetzt
setcookie('stayloggedin', $zufallcode, time() + (86400 * 30), '/');
// ... und in den Datensatz geschrieben
$sql = "UPDATE nutzer SET stayloggedin='$zufallcode' WHERE id='$id'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
} else {
// falls bereits ein Datensatz vorhanden ist, wird der Zufallscode aus der DB ausgelesen und als Cookie gespeichert
setcookie('stayloggedin', $db_stayloggedin, time() + (86400 * 30), '/');
}
}
Prüfung im Nutzerbereich
PHP-Code:
// Wenn der Stayloggedin Cookie gesetzt ist
if (isset($_COOKIE['stayloggedin'])){
$stayloggedin = $_COOKIE["stayloggedin"];
// Nutzerdatenbank nach Inhalt des Cookies durchsuchen
$statement = $pdo->prepare("SELECT * FROM nutzer WHERE stayloggedin = '$stayloggedin'");
$result = $statement->execute(array('stayloggedin'));
$daten = $statement->fetch();
$stayloggedindb = $daten['stayloggedin'];
// Nutzer ID
$id = $daten['id'];
// Wenn der Hash aus dem Cookie mit dem in der Datenbank übereinstimmt ...
if($stayloggedin == $stayloggedindb){
// ... dann Cookie erneuern
setcookie('stayloggedin', $stayloggedin, time() + (86400 * 30), '/');
// ... und Session setzen, Nutzer einloggen
$_SESSION['id'] = $daten['id'];
}
}
Kommentar