PHP-Sessions

Ich habe immer wieder miterlebt, dass Neulinge nicht verstehen, welche geniale Idee sich hinter PHP-Sessions versteckt. Sie verwenden $_SESSION und setzen session_start(), aber verstehen muss man es scheinbar nicht wirklich. Ich werde es einmal hier erklären und hoffe, dass der eine oder andere die Genialität erkennt.

Serverseitig
Serverseitige Speicherung von Daten ist kein Problem. Wir können in Datenbanken schreiben, in Textdateien oder die Daten bei jedem neuen Aufruf erzeugen. Die Daten können persistent gespeichert werden. Auf die Daten kann dann idealerweise nur das Skript selbst zugreifen und somit sind die Daten sicher vor Angreifern geschützt, die die Passwörter lesen möchten. Jedoch gibt es keine Variante den User zu einem Datensatz zuzuordnen. Das ist der große Nachteil. Die Useridentifikation ist ein grundlegendes “Problem” (wer für Anonymität im Internet ist, wird jetzt “Glück” sagen) von HTTP.

Das Useridentifikationsproblem
Das Grundproblem ist, dass HTTP verdammt stark an Amnesie leidet und nach Ablauf des Datentransfers alles wieder vergisst. Wir verlieren sämtliche Daten, die wir einfach in einer Variable ablegen.

Clientseitig
Abhilfe sollen dafür Cookies schaffen. Cookies sind kleine Textdateien, die temporär am Rechner des Clients abgelegt werden. Ob Cookies abgespeichert werden, ist natürlich nicht sicher. Der HTTP-Header kann nur “bitten” die Daten zu speichern. Ob sie angenommen werden, ist unklar. Es gibt auch keine effiziente Methode herauszufinden, ob der Client Cookies akzeptieren wird oder nicht. Wird es jedoch akzeptiert, hat man die Möglichkeit einen Namen einem Inhalt zuzuordnen. Somit hätten wir das Problem gelöst. Wir können die Daten auf dem Client speichern und damit funktioniert die Useridentifikation wunderbar. Und die Cookies bleiben auch erhalten (Daten sind persistent). Nach Ablauf des Datentransfers bleiben die Cookies gespeichert und bei der nächsten Anfrage an den Server werden die Cookies mitgesendet. Jedoch haben wir bei Cookies ein sicherheitstechnisches Problem: Wir können nicht Usernamen, Passwort oder andere heikle Daten auf dem Client speichern. Die kann der Client ganz leicht ändern und der Client erhält nun statt dem Usernamen “MeisterLuk” den Namen “admin”. Sämtliche Daten, die am Client gespeichert werden, sind unglaubwürdig!

Zusammenfassung
Ich fasse nochmals kurz zusammen:

  • Wir können serverseitig wunderbar sämtliche Daten speichern und sie sind sicher vor Hackern. Jedoch ist es schwer einem User einen Datensatz zuzuordnen.
  • Wir können clientseitig jedem Benutzer beliebig viele Cookies mitgeben und können dann jedem User einen Datensatz zuordnen. Jedoch sind Daten vom Client unglaubwürdig, weil er sie leicht ändern kann. Wir können somit keine sensiblen Daten speichern

Die Lösung des Problems ist eine Technik, die die Vorteile beider Techniken zusammenfasst:
PHP-Sessions
Die geniale Idee von PHP-Sessions ist es am Client eine Identifikationsnummer zu speichern. Dieser Identifikationsnummer wird am Server ein Datensatz zugeordnet. Sprich: Wir speichern am Client ein Cookie mit dem Namen (zB) “SID” (für “Session-Identification”) und speichern darin einen einzigartigen Wert, der den User identifiziert. Bei einer Anfrage (zB einer Webseite) wird diese SID an den Server geschickt. Dieser sucht den Datensatz mit der SID. Und diesem Datensatz befinden sich zB Username und Passwort. Da der Benutzer nie die serverseitig gespeicherten Daten zu Gesicht bekommt, sind die Daten sicher und glaubwürdig. Akzeptiert der User den Cookie mit der SID nicht, so bekommt er einfach keinen Zugang (zB zu einem Administratorenbereich). Jetzt könnte noch jemand auf die Idee kommen und sagen: was ist wenn ich so lange die (clientseitig gepsicherte) SID so umändere, bis ich die SID vom Administrator erhalte? Die Wahrscheinlichkeit, dass du im Lotto gewinnst ist größer als die Wahrscheinlichkeit die SID vom Administrator zu erfahren (ich weiß leider nicht mehr die genaue Zahl). Wenn du ein Sicherheitsfanatiker bist, kannst du auch eine zweite SID hinzufügen, weil sich die Wahrscheinlichkeit dann exponentiell vergrößert. Man kann SIDs auch an die URL anhängen und sie somit über GET mitsenden. Diese Variante ist jedoch eher unsicher, weil Leute gerne den vollen Link mitsenden und somit auch ihre SID. Man sollte die Cookies-Variante bevorzugen. Oder im Idealfall beides. Auf die PHP-SID kann mit session_id() zugegriffen werden. Somit wirken beide Nachteile der Techniken nicht mehr.

Wen es interessiert: Die Aufgabe einen Datensatz einer SID zuzuordnen übernimmt nicht der Programmierer. Sämtliche Daten werden einfach in $_SESSION gespeichert und sind beim nächsten Webseitenaufruf verfügbar. Es ist nur notwendig session_start() vor dem Ablauf des Skripts zu starten. PHP speichert die $_SESSION-Daten in einem temporären Verzeichnis. Bei einem XAMPP befinden sie sich in tmp/. Ein guter Webhoster erlaubt auch Zugriff auf dieses Verzeichnis. Hat der Server irgendwelche serverseitigen Probleme mit Sessions (kommt nur selten vor), löscht man alle Dateien des Verzeichnis’ und das Problem ist gelöst.

  1. In Hagenberg haben wir eine Methode gelernt, wie man noch sicherer mit Sessions arbeiten kann: Man speichert Browser & IP-Adresse verschlüsselt als “Token” ebenfalls als Sessionvariable. Dadurch muss man mit ziemlicher Sicherheit am gleichen PC sein als der Admin, um seine SID überhaupt erraten zu können ;)

  2. Lukas Prokop

    Jepp, wie im Beitrag erwähnt gibt es sogar Sicherheitsfanatiker, die gleich zwei Session-IDs simulieren. Sprich 2 Cookies, 2 GET-Variablen oder halt kombiniert anlegen. Dadurch wächst die Wahrscheinlichkeit, die Session zu erraten, exponentiell gegen Null. Die Frage ist halt immer wo ist die Grenze? Die Fehleranfälligkeit steigt auf jeden Fall. So kann sich ja in deinem Beispiel schnell die IP-Adresse ändern, wenn sie dynamisch ist.

    Was ich auf jeden Fall noch ausprobieren möchte ist es mit PHP-Session objektorientiert zu arbeiten. Sozusagen wird jeder User als Objekt betrachtet. Durch die OOP kann dies für eine Zugriffsstatistik sehr hilfreich sein. Aber OOP und PHP kann ich sonst gar nicht vertragen. OOP braucht man für normale Webseiten nicht wirklich und macht es nur komplizierter.

  3. Frédéric Gierlinger

    Ist es nicht so, dass SessionID’s vom Client gelöschte werden, sobald der Client den Browser schliesst?
    @Lukas: Ich habe es ausprobiert und es ist wirklich so, dass die SessionID’s CLIENT(!!!) seitig nicht gespeichert werden.
    Bitte um Aufklärung ;)

  4. Lukas Prokop

    Es hängt natürlich davon ab, ob die PHP-Sessions mit GET oder mit Cookies verwendest. Die Standardmethode sind Cookies. Und die legt PHP an. Der Defaultname ist in der php.ini unter “session.name” festgelegt und sonst kann man ihn mit session_name() festlegen.

    Was jetzt “Browserfenster schließen” für technische Bedeutung haben soll, bleibt der Clientkonfiguration überlassen.

    Wenn ich jetzt das Cookie wordpress_$VAR lösche, bin ich nicht mehr als “admin” angemeldet.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>