Mailinglisten-Archive |
Hi! (Entschuldigt bitte das "CrossPost" dieser Mail von der PHP-Newsgroup, aber ich hoffe, daß mir in einer der beiden Foren jemand helfen kann...) Vor schon etwas längerer Zeit habe ich eine Seite entwickelt, die anfangs eine kleine Sessionverwaltung haben sollte, nur um für eingeloggte User ein paar Links darzustellen. Über die Zeit ist das ganze nun etwas gewachsen, jedoch setzt die Session-Funktionalität immer noch auf meine ganz alten Funktionen auf. Damals habe ich mich gegen den Einsatz von PHPLib entschieden, weil ich etwas dazulernen wollte. Nun habe ich heute von einen meiner Betatester etwas schreckliches gehört: Jemand meinte, er habe die Seite ganz normal aufgerufen, und sei in die gültige Session eines anderen Benutzers reingelangt. Ohne irgendwo Benutzerkennung und Passwort einzugeben, wurde dem Benutzer angezeigt, er wäre als Benutzer XYZ eingelogged. Momentan bin ich echt ratlos, was ich da falsch gemacht haben könnte. Als Webserver ist Apache 1.3.14 im Einsatz, als PHP-Version die 4.0.4pl1. Ein Auszug aus der php.ini: --> php.ini <-- safe_mode=Off max_execution_time=30 memory_limit=8M variables_order="EGPCS" register_globals=On register_argc_argv=On magic_quotes_gpc=On magic_quotes_runtime=Off magic_quotes_sybase=Off session.save_handler=files session.save_path=/tmp session.use_cookies=1 session.name=SID session.auto_start=0 session.cookie_lifetime=0 session.cookie_path=/ session.cookie_domain= session.serialize_handler=php session.gc_probability=1 session.gc_maxlifetime=1440 session.referer_check= session.entropy_length=0 session.entropy_file= session.cache_limiter=nocache session.cache_expire=180 session.use_trans_sid=0 <-----------------------------> Hier habe ich jetzt noch einen kurzen Auszug aus meinen Scripten, die eigentlich alles meiner Benutzererkennung ausmachen. Prinzipiell verläßt sich alles darauf, ob eine Variable $user["auth"] auf "true" gesetzt ist, und diese Variable wird ja in der Session-Datei gespeichert. D.h. eigentlich dürfte man nur als eingeloggter Benutzer erkannt werden wenn: 1. Man eine Session-ID vorweist, in der PHP bereits die Variable auf true gesetzt hat oder 2. Man eine Session-ID besitzt, der man im laufe der Session diese Variable zugewiesen hat. Letzteres ist nur durch meine Skripte möglich, und eigentlich durch Eingriffe von aussen geschützt. Meine Scripts sind jetzt nicht wirklich das bombensicherste, weil ich z.B. häufig Globale-Variablen verwendet habe. Aber das habe ich wenigstens konsequenz gemacht, und vorige Get/Post-Variablen immer gelöscht. Der Benutzer, der mir berichtete, den Zugriff auf jemand anders zu haben, hatte die Seite vorher schonmal besucht, und hat vermutlich auch schon einen Cookie von der Seite erhalten...kann es nun irgendwie sein, daß ihm eine Session-ID eines noch gültigen Users (also unter der gc_maxlifetime) von PHP oder dem Zufallsgenerator zugewiesen wurde? Oder sind meine Routinen so fehleranfällig/sicherheitslöchig, daß es dazu kommen mußte? Ich wäre wahnsinnig dankbar, wenn mir jemand einen Tip geben könnte, denn so ein riesiges Loch hat ja keiner gerne in seinen Seiten. ;) Hier meine Code-Schnippsel: <-- INDEX.PHP --> unset($user); session_start(); include "FUNKTIONEN.PHP"; echo "<body>"; Menu($user, $HTTP_COOKIE_VARS); echo "</body>"; echo "</html>"; <-------------------------------------------------------------------> <-- FUNKTIONEN.PHP --> function Menu($user, $HTTP_COOKIE_VARS) // HTML-Menu erstellen. { // Standard-Kopf einer HTML-Seite (Menu) ausgeben if ($user["usermail"] != "") { echo $user["usermail"]; // Ausgabe der Benutzerkennung im Menu, falls // Benutzer schon eingelogged. } elseif (isset($HTTP_COOKIE_VARS["account"]) // Wenn der Benutzer nicht eingelogged ist, aber ein // Cookie auf den Benutzernamen gesetzt wurd, wird // dieser ausgegeben { echo $HTTP_COOKIE_VARS["account"]; } $reauth = "false"; // Re-Authorisierung soll erstmal nicht erforderlich // sein if ($user["auth"] == "true") // Dies ist meine Haupt-Session-Variable, sie // beschreibt ob ein User eingelogged ist oder nicht. { $zeit = authtime($user["usermail"]); // Diese Funktion prueft, ob der Benutzer schon // laenger als 10 Minuten inaktiv war. if ($zeit[2] == "true") // Falls diese Zeit noch nicht erreicht wurde, wird // der aktuelle Timestamp neu gesetzt. { authsettime($user["usermail"]); // Timestamp neusetzen } else { $user["auth"] = "false"; // Benutzer muss sich neu authentifizieren. session_register("user"); // Session-Variable speichern $reauth = "true"; // Re-Authorisierung ist notwendig. } } if ($user["auth"] == "true") // Falls der Benutzer nun noch als eingelogged anerkannt // wird, einige Benutzerspezifische Daten ausgeben... { // Spezielle Links darstellen, die nur fuer // eingeloggte Benutzer gelten. } if ($reauth == "true") // Falls Re-Authorisation notwendig ist... { login($user, "index.php", "index-user.php", "Login"); } } function login($user, $start, $root, $text) // Login-Fenster anzeigen. Returns $page (ARRAY) { $user["targetpage"] = $target; // Zielseite sichern $user["rootpage"] = $root; // Quellseite sichern session_register("user"); // Formular mit Feldern fuer Userkennung und Passwort einblenden. // Formular zeigt auf TRANSFER.PHP if ($user["loginerror"] != "") // Falls ein voriger Login schon stattfand und Fehler beinhaltete, // diesen nun anzeigen und loeschen. { // Vorige Fehlermeldung ausgeben unset($user["loginerror"]); // Fehlermeldung loeschen session_register("user"); // Geloeschte Fehlermeldung speichern. ;) } } <-------------------------------------------------------------------> <-- TRANSFER.PHP --> ignore_user_abort(true); unset($user); // Verhindern, dass die Variable irgendwie auf die Datei "getrickst" // wird. session_start(); setcookie("account", $HTTP_POST_VARS["usermail"], time()+time(), "/"); // Usernamen vom Login-Formular im Cookie sichern. $user["usermail"] = $HTTP_POST_VARS["usermail"]; // Variable vom HTML-Formular speichern. $target = $user["targetpage"]; $val = validate($user["usermail"], $HTTP_POST_VARS["passwort"]); // Login auf Gueltigkeit pruefen. Gibt Array zurueck. Index 0 enthält // true|false und Index 1 die Benutzer-ID if ($val[0] == "true") { $user["id"] = $val[1]; // BenutzerID sichern $user["auth"] = "true"; // Benutzer als gueltig anerkennen authsettime($HTTP_POST_VARS["usermail"]); // Den Timestamp des Benutzers auf aktuelle Zeit setzen session_register("user"); // Sessionvariablen speichern header("Location: $target"); // Umleitung auf zielseite } else { switch($val[0]) // Wenn der Benutzer nicht gueltig validiert wurde { case "noemail": // Keine gueltige E-Mail Adresse gegeben $user["auth"] = false; $target = $user["rootpage"]; $page["error"] = "Keine E-Mail Adresse"; session_register("user"); header("Location: $target"); break; case "nopassword": // Kein gueltiges Passwort $user["auth"] = false; $target = $user["rootpage"]; $page["error"] = "Kein gueltiges Passwort"; session_register("user"); header("Location: $target"); break; default: $user["auth"] = false; $target = $user["rootpage"]; $page["error"] = "Keine Uebereinstimmung"; session_register("user"); header("Location: $target"); break; } } ignore_user_abort(false); <-------------------------------------------------------------------> <-- LOGOUT.PHP --> session_start(); setcookie(session_name(), "", 0, "/"); setcookie("account", $user["usermail"], time()+time(), "/"); session_destroy(); header("Location: index.php"); <-------------------------------------------------------------------> (Danke an alle, die die Mail bis hierhin gelesen haben. :-) -- Bye .:~~[ Atrava Design & Computer ]~~:. | Garvin Hicking - ICQ 21392242 | Garvin. `....[ http://www.atrava.de/ ]....'
php::bar PHP Wiki - Listenarchive