HTTP ist ein zustandsloses Protokoll, daher kann ein Webserver einen Benutzer nicht dauerhaft zuordnen. Das heißt, nach einem erfolgreich bearbeiteten Request (Seitenaufruf) wird die Verbindung beendet und bei einem erneuten Aufruf kann keine Verbindung mehr zum vorherigen Aufruf hergestellt werden. Daher verwendet PHP Sessions, um einen Benutzer eindeutig zuordnen zu können. Beim ersten Aufruf wird dem Client eine Session-ID mitgeteilt, diese schickt er mit jeder Anfrage an den Server und kann so eindeutig identifiziert werden. Ich möchte hier nicht weiter auf die Funktionsweise eingehen, sondern mich auf die Sicherheit der Übertragung der Session-ID mit PHP konzentrieren. Hier gibt es weitere Informationen für den Einstieg in das Thema:
+ PHP Tutorial – Sessions
+ SEO-freundliches, Cookie-unabhängiges Session-Handling in PHP
+ PHP Session-Management erklärt
Es gibt zwei Möglichkeiten, wie eine Session-ID übertragen werden kann: zum einen als Attribut in der URI und zum anderen als Wert innerhalb eines Cookies. Die Übertragung in der URI ist grundsätzlich keine gute Idee, da diese viel zu häufig im Klartext auftaucht, zum Beispiel im Web-Browser Verlauf und in Proxys. Jedoch können auch Web-Browser Plugins darauf zugreifen. Daher sollte diese Methode gar nicht verwendet werden und ich gehe hier im Folgenden nur noch auf die Speicherung im Cookie ein.
Vornweg ein paar grundsätzliche Punkte, die jedoch nicht oft genug wiederholt werden können:
+ Vertrauen Sie niemals externen Daten. Auch Session-IDs sind Daten, die von Benutzern übermittelt werden und müssen daher entsprechend gefiltert werden.
+ Verwenden Sie ausschließlich TLS/SSL-Verbindungen, wenn Authentifizierungen oder Benutzerdaten übertragen werden.
+ Verlassen Sie sich niemals nur auf eine Sicherheitsleistung auf einer Ebene, sondern setzten Sie auf eine gestaffelte Abwehr auf mehrere Ebenen – Stichwort Defense in Depth.
Mit diesen Punkten kann eine Session in PHP abgesichert werden:
+ Session-IDs sollten erst bei der Anmeldung für einen Benutzer generiert werden. Musste dies bereits davor erfolgen, sollte die ID mit der Anmeldung neu generiert werden.
+ Eine Sitzung sollte automatisch auslaufen (Timeout), sobald keine Interaktion mehr erfolgt und den Benutzern sollte eine einfache Methode zur Abmeldung zur Verfügung gestellt werden. Dadurch wird der Zeitraum für einen Angriff minimiert.
+ Weitere Details wie IP-Adresse oder die Web-Browser Kennung sollten zu jeder Session gespeichert werden und bei jedem Aufruf überprüft werden. Damit kann eine geklaute Session erkannt und die Sitzung sofort beendet werden. Aber Vorsicht, diese Parameter können sich auch bei normalen Nutzern (z.B. im Mobilfunknetz) ändern.
+ Für zusätzliche Sicherheit kann die Session-ID mit jedem Request ausgetauscht werden. Erfolgt eine Anfrage mit einer alten Session-ID, wird der Benutzer abgemeldet. Dies kann aber zu Problemen führen, wenn der Benutzer zum Beispiel mehrere Tabs verwendet.
+ Weitere Details zur Sitzung, wie der Benutzername oder der Zeitpunkt des Logins, sollten nur auf dem Server gespeichert und nicht mit dem Cookie übertragen werden. Cookie-Inhalte können relativ einfach manipuliert werden.
+ Der Zugriff auf den Cookie mit der Session-ID durch JavaScript sollte verhindert werden. Dies kann durch das Setzen der Cookie-Option HttpOnly geschehen.
+ Der Cookie mit der Session-ID sollte nur mit einer TLS/SSL-Verbindungen übertragen werden. Dies kann durch das Setzen der Cookie-Option secure erfolgen.
Wer sich noch intensiver mit dem Thema auseinandersetzen möchte, findet hier noch weitere Information zur Absicherung der Login-Session in PHP:
+ Sessions und Sicherheit
+ How to Create Bulletproof Sessions
+ Session Fixation
+ PHP Session mit Timeout-Funktion
[UPDATE] 17.112.2017 Diesen Blog-Artikel habe ich von meinem Web Developer Blog auf meinen Hauptblog scheible.it umgezogen. Ein paar Punkte habe ich aktualisiert und um weitere Information ergänzt. [/UPDATE]
Ich überlege mir ein Forum zu erstellen. Ist PHP die beste Variante oder gibt es bessere Systeme?