Passwortgeschützter Bereich mit PHP und MySQL
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
adresse
aufruf
bereich
browser
code
dank
datei
datenbank
datensatz
datum
feld
frage
jemand
letzten beitrag
pfad
server
session
string
url
zugriff
-
Hallo,
ich würde gern einen passwortgeschützten Bereich einführen mit Hilfe von PHP und MySQL: folgendes habe ich mir überlegt:
1. Angenommen, in einer Datenbanktabelle sind bereits (über ein entsprechendes Formular) die User gespeichert in der Form ID - Username - Passwort (verschlüsselt)
2. Über ein Login-Formular kann der User Username und Passwort eingegeben ... das wird per POST an den Server gesendet und mit den Daten in der Datenbank verglichen.
3. Wenn es einen Eintrag gibt, wird a) im Array $_SESSION ein Feld 'LogKey' angelegt, gefüllt mit einem zufällig generierten Code (Kombination aus shuffle und md5), sowie in einer 2. Datenbanktabelle 'Temp' ein neuer Eintrag angelegt mit den Feldern ID (=der generierte Code) und Time (=Timestamp).
4. Auf jeder zu schützenden Seite wird dann eine checklogin.php eingebunden, die überprüft, ob der in der Session gespeicherte Code dem Feld ID eines Datensatzes in "Temp" entspricht. Wenn dem nicht so ist, bricht das Script ab ( die (""); ), andernfalls wird der aktuelle Timestamp in den Datensatz in Temp geladen.
5. Beim Ausloggen wird sowohl die SESSION-Variable als auch der Datensatz in Temp gelöscht.
6. Aus Sicherheitsgründen und falls jemand vergisst, sich auszuloggen, wird zusätzlich alle 10 min (oder so) ein CronJob (www.cronjobs.de) ausgeführt, der alle Datensätze in Temp, deren Timestamp älter als 10 min ist, löscht. So erfolgt nach höchstens 20 minütiger Inaktivität ein automatischer Logout.
Was haltet ihr davon? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Im Prinzip keine schlechte Idee, aber die Sessions werden auf dem Webserver verwaltet. Bei jedem Seitenaufruf gibt die Session ID vor, welche Session Datei ausgelesen wird. Wird also die richtige Session ID von einem Fremden an den Webserver übergeben, so stimmen automatisch Deine beiden Werte überein und Du kannst nicht erkennen, ob ein Unbefugter gerade diese Session benutzt.
Du musst also bei jedem Aufruf in der checklogin.php überprüfen, ob die aufrufende IP-Adresse noch mit der Original-IP-Adresse, die beim Login benutzt wurde, übereinstimmt. Du könntest den Hash Wert auch als Cookie beim User abspeichern und dann so jedes Mal prüfen. Oder du nimmst noch einen Hash-Wert, den Du aus Browserkennung und anderen Merkmalen generierst und speicherst diesen bei Anmeldung in der Session und überprüfst dann bei jedem Aufruf, ob IP, Browser und weitere Merkmale den gespeicherten Hash ergeben.
Die Session-Daten (also die $_SESSION Variable) halten bei Lima-City sowieso nur 1440 Sekunden = 24 Minuten. Dann werden verwaiste Sessions automatisch vom Garbage Collector gelöscht. Dann ist der gespeicherte Hash weg, die in der Datenbank gespeicherte Prüfversion bringt dir dann auch nichts mehr. Mir passiert das immer wieder, dass ich Session-Daten auslesen will, aber diese schon durch zu lange Inaktivität gelöscht wurden.
Und wenn Du eine unbefugte Nutzung festgestellt hast, solltest Du unbedingt die SESSION Variablen über unset($_SESSION), oder session_unset() löschen, erst danach die Session mittels session_destroy() zerstören. Meine Erfahrung hat gezeigt, dass ohne Löschen die Daten trotzdem beim nächsten session_start() zur Verfügung stehen.
edit:
Du könntest in diesem Thema nochmal stöbern, da haben wir vor kurzem über Sicherheit von Sessions gesprochen. http://www.lima-city.de/thread/php-sessions-sicherheit-maximieren
Beitrag zuletzt geändert: 10.9.2010 15:14:16 von rnitsche -
Hallo rnitsche,
danke für die Hinweise und die Weiterleitung zu dem anderen Forenbeitrag ... im Grunde ist es ja schon sinnvoll, wie der eine Beispielcode zum fingerprint zeigt, über $_SERVER[SERVER-ADDR] das ganze zu validieren ... weil dann ja nur Scripts erlaubt sind, die von meinem Server aus gestartet werden ... naja, bringt 1. nichts, wenn mein eigenes Script mittels ?irgendwas=inhalt angesprochen wird, 2. problematisch allerdings wie bei lima-city.de, wenn auch andere Seiten auf dem gleichen Server liegen, die von anderen verwaltet werden können ... dann vielleicht doch zusätzlich noch über die IP-Adresse + Browser ...
Was ich mich frage: wie kann denn überhaupt ein anderer die SessionID an den Server übergeben außer via Query-String? Und das kann ich ja überprüfen mit: if($_SERVER['QUERYSTRING']) {die();} oder so ähnlich ...
Wie ist das denn bei Dateien? Angenommen, in dem Passwortgeschützten Bereich sollen Dateien zum Runterladen angeboten werden ... diese habe ich ja aber vorher irgendwo auf meinem Webspace gespeichert, z.B. unter public_html/Data/GeheimesDokument.pdf ...
Jetzt könnte ja aber jeder, der den Pfad kennt, hergehen und über MeinName.lima-city.de/Data/GeheimesDokument.pdf die Datei runterladen, denn eine checklogin.php kann ich hier ja nicht vorher einbinden?
Aber vielleicht gibts da ja andere Möglichkeiten?
Beitrag zuletzt geändert: 10.9.2010 20:30:32 von jugend-bewegt -
Ja, das stimmt. Wenn jemand den Pfad kennt, kommt er ohne Passwortschutz an die geschützten Bereiche. Aber wenn Du nirgendwo öffentlich verlinkst und auch das Directory Indexing in Deinem Webspace deaktiviert hast, sollte keiner (und keine Suchmaschine) die Pfade zu den Dateien kennen.
Alternativ gibt es die Möglichkeit, diese Dateien in einen Ordner zu legen, diesen mittels einem deny from all in einer .htaccess Datei vor jeglichem Zugriff zu schützen und dann später über das PHP Skript zur Verfügung zu stellen, siehe dazu PM.
Beitrag zuletzt geändert: 10.9.2010 20:58:08 von rnitsche -
Danke für die schnelle Antwort ...
1. habe gerade meinen letzten Beitrag nochmal überarbeitet hinsichtlich der Frage des QueryStrings und dem Zugriff auf die Session ... vielleicht kannst Du dazu kurz was sagen ...
2. Danke auch für den Hinweis mit den Dateien ... bin leider in Abkürzungen nicht firm, solange sie nicht selbst erklärend sind ... was meinst Du mit PM ... oder länger: wie würde ich denn die Dateien dann im phpscript zur Verfügung stellen ...
3. Wäre es - wenn ich sowieso SESSION via Cookies verwende - dann nicht besser, wenn ich gleich über setcookies ein Cookie mit einem entsprechend generierten Code anlege und den mit dem Code in der Datenbank vergleiche?
Beitrag zuletzt geändert: 10.9.2010 20:44:01 von jugend-bewegt -
jugend-bewegt schrieb:
Was ich mich frage: wie kann denn überhaupt ein anderer die SessionID an den Server übergeben außer via Query-String?
Genau so ist das. Normalerweise wird die Session-ID als Cookie gespeichert. Es gibt aber auch die Möglichkeit, an die URL den Querystring '&SESSID=Session-ID' anzuhängen. Beim Aufruf von session_start() erkennt PHP automatisch, dass es die Session-ID aus dem Querystring nehmen soll. Daher ist standardmäßig das automatische Anhängen der Session-ID ausgeschaltet.
Denn wenn jemand während des Besuchs einen Link postet mit seiner eigenen aktuellen Session-ID oder irgendjemand sich die ID mittels Session-Hijacking Methoden krallt, hätte er sofort Zugriff. Wenn Du aber die IP-Adresse prüfst, kannst Du so einen Angreifer dann aussperren.
Und PM (bzw. PN auf deutsch) steht für Private Nachricht, oder private message. Habe Dir gerade Anleitungen in Deinen Postkasten geschickt.
zu 3.) es gibt hier immer pros und contras für die PHP-Session Verwaltung und genauso für die eigene Session-Verwaltung per Datenbank. Die Lösung ist Geschmackssache. Im Endeffekt setzt du mit deinem Vorschlag dann ein eigenes Session Management um.
Beitrag zuletzt geändert: 10.9.2010 20:45:29 von rnitsche -
Danke für die Aufklärung mit PM (PN) ...
wiederum warst Du schneller oder ich zu ungeduldig ... wieder habe ich bereits meinen Beitrag überarbeitet ...
1. Deiner Antwort entnehme ich, dass eine Überprüfung des QUERY-Strings das SESSION-Hijacking verhindern sollte ...
2. Wie ist das dann mit Cookies, kann ich mir dann nicht gleich die Sache mit den $_SERVER-Variablen sparen? (s. meinen letzten Beitrag) ... -
jugend-bewegt schrieb:
1. Deiner Antwort entnehme ich, dass eine Überprüfung des QUERY-Strings das SESSION-Hijacking verhindern sollte ...
Sorry wenn das falsch rüber gekommen ist. Die Überprüfung des QUERY Strings verhindert das Session Hijacking nicht. Gerade weil PHP diesen String automatisch zum Auslesen der ID heranzieht bringt das ja eine Gefahr mit sich. Daher sollte man beim Anmelden in der Session die IP-Adresse (und evt. weiteres wie die Browserkennung) speichern. Dann bei jedem Aufruf prüfen, ob die IP-Adresse noch mit der Adresse bei Anmeldung übereinstimmt. Sollte die Session geklaut worden sein, hat sich auch die IP-Adresse / und der Browser verändert und daher kann man dann die Session schließen..
z.B. so
if($_SERVER['REMOTE_ADDR'] != $_SESSION['ip']) // Session Weitergabe festgestellt { session_unset(); session_destroy(); }
2. Wie ist das dann mit Cookies, kann ich mir dann nicht gleich die Sache mit den $_SERVER-Variablen sparen? (s. meinen letzten Beitrag) ...
Cookies werden beim Client gespeichert und könnten rein theoretisch auch geklaut werden. Daher sollte man immer auf der Serverseite bestimmte Merkmale speichern und diese wie oben beschrieben mit aktuellen Werten vergleichen.
Beitrag zuletzt geändert: 10.9.2010 20:56:40 von rnitsche -
Gut, danke, die Variante der Überprüfung bestimmter Eigenschaften hätte ich sowieso umgesetzt ...
Jetzt muss das ganze aber auch mal als Script tatsächlich geschrieben werden ... hab also erstmal zu tun ...
Nochmal zum QUERYSTRING - habe gerade folgendes probiert: auf Seite 1 wird eine Session gestartet und an Seite 2 mit der Konstanten SID (bzw. auch mit ?&SESSID) angehangen ... wenn ich dort allerdings bevor ich die session_start() aufrufe, überprüfe, ob ein String angehangen wird mit if($_SERVER['QUERYSTRING']), und falls ja, das Skript beende, dann wird auch die Session nicht mehr aufgerufen ... funktioniert also ...
deshalb verstehe ich nicht, wieso dann dieser Vorgang (zusätzlich zu den anderen) nicht vor SESSION-Hijacking schützen sollte, denn eine Übergabe über den Querystring wäre ja dann nicht mehr möglich (allerdings auch die Übergabe anderer Parameter nicht, was ja aber auch über Datenbank gelöst werden kann) ...
das funktioniert auch, wenn ich die QUERYSTRING-Abfrage in einer Datei druchführe, die in beispiel.php inkludiert ist und beispiel.php mit einem Querystring ausgeführt wird ...
Beitrag zuletzt geändert: 10.9.2010 21:33:47 von jugend-bewegt -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage