Quakenet/#php Tutorial

Hinweis: Wenn sie diese Seite von einer externen URL aufgerufen haben achten sie darauf das alle Kapitel aufeinander aufbauen. Stellen sie daher sicher dass sie alle vorherigen Kapitel gelesen haben, da sie sonst relevante Informationen übersehen.

Sessions

  1. Was ist eine Sitzung?
  2. Sessions in PHP
  3. Session-IDs
  4. Erzeugen bzw. laden einer Session
  5. Session benutzen
  6. Übermitteln der Session-ID
  7. Dauer einer inaktiven Session
  8. Sicherheit von Sessions

1. Was ist eine Sitzung?

Je nach Definition ist eine Sitzung etwas, was über einen längeren Zeitraum andauert. In unserem Fall könnte man z.B. Denken es ist damit der Zeitraum zwischen Beginn und Ende der Internetbenutzung, die an einem Stück stattfindet. Wenn man jetzt vom Flatrate-Verhalten absieht könnte z.B. die Internetnutzung an der Arbeit um 9:00 Beginnen und um 12:00 enden. Diesen Zeitraum nennt man dann Sitzung.

Für Webserver (und somit für PHP) existiert der Begriff Sitzung nicht so wie wir ihn kennen, besonders nicht in dieser zeitlichen Länge. Für ihn ist eine Sitzung vom Verbindungsaufbau vom Client bis zum Senden der Antwort (meist HTML-Code), oder schlicht einfach die Dauer des Requests. Dabei ist jede Anfrage in sich geschlossen, es gibt (für den Webserver) keine semantische Verbindung zwischen zwei Anfragen. Dies kann unerwünscht sein, wenn man sich z.B. das beliebte Beispiel eines Warenkorbs eines Internetshops anguckt. Dort würde man eine Sitzung mit der Verweildauer im Internetshop gleichsetzen. Denn die Produkte die der Kunde ausgewählt hat müssen im Warenkorb hinterlegt werden und wenn er zur Kasse geht wird der Warenkorb ausgelesen und die Bestellung wird abgeschlossen. Was für den Benutzer wie eine lineare Führung durch den Bestellprozess ist ist für den Webserver nichts anderes als voneinander unabhängige Requests von beliebige Clients. Er weiß nicht das der Request vor 5 Sekunden semantisch zum aktuellen Request passt.

2. Sessions in PHP

Wenn wir Daten von einem Skript an ein anderes Skript schicken benutzen wir z.B. Links mit GET-Variablen oder Formulare mit hidden-Feldern. Dabei stoßen wir auf einige Grenzen denn wir sollten keine überlange URLs generieren die alle Daten enthalten die wir weitersenden wollen. Auch sollten wir keine Formulare mit riesigen hidden-Feldern. Und es könnte abenteuerlich werden wenn wir versuchen Arrays weiterzuleiten.

Aus all den Problemen mit der Datenweitergabe gibt es in PHP ein Sitzungs-System, kurz Sessions. Das heißt das man sich als Programmierer nicht mehr so viel Gedanken machen muss wie man Daten von einem Skript an das nächste Skript übergibt. Denn bei Sessions wird nur eine Identifikationsmarke weitergereicht.

3. Session-IDs

Da für ein Webserver jeder Request unabhängig von den anderen ist müssen wir in PHP irgendwie die richtige Session auswählen die wir (weiter)verwenden wollen. Daher brauchen wir eine Identifikation für die zu wählende Session. Spontan könnte man an folgende Beispiele denken.

Immer wenn eine Session generiert wird wird auch eine zufällige Identifikation erstellt, die sog. Session-ID. Mit dieser findet der Webserver die richtige Session wieder. Da diese Session-ID reicht um die richtige Session wiederzufinden reicht es auch nur diese Session-ID an das nächste Skript zu schicken. Wenn das nächste Skript die Session-ID sieht kann es die vorherige Session anhand dieser ID wieder laden. Wenn man also URLs der Form index.php?PHPSESSID=6ead67974b4a6794... sieht... das ist die Session-ID.

4. Erzeugen bzw. laden einer Session

Um in PHP eine Session zu starten bzw. zu erzeugen wird die Funktion session_start verwendet. Die selbe Funktion wird auch verwendet um eine vorherige Session zu starten. Somit braucht man sich keine Gedanken machen ob man nun eine alte Session laden möchte oder ob man eine neue beginnen möchte da man so oder so nur eine Funktion verwendet. Wenn eine Session-ID übergeben wurde und unter dieser ID eine Session vorhanden ist so läd die Funktion session_start die Session wieder. Wenn keine Session mit der angegebenen Session-ID gefunden wurde oder überhaupt keine Session-ID angegeben ist wird eine neue Session generiert.

5. Session benutzen

Nachdem eine Session erzeugt bzw. geladen wurde legt PHP ein neues Superglobales Array $_SESSION an. In diesem Array können nun alle Daten gespeichert werden die man möchte. Da es ein normales Array ist wird es auch wie ein normales Array benutzt.

<?php
session_start
();
// nun haben wir $_SESSION
$_SESSION['Foo'] = 'Bar';
echo 
$_SESSION['Username'];
?>

Man kann mit dem Array alles machen, jedoch sollte man nicht das ganze Array als solches mit unset($_SESSION); löschen. Die Session wird abgespeichert wenn das PHP-Skript zuende ist oder die Funktion session_write_close aufgerufen wird, je nach dem was früher eintritt. Dann wird das $_SESSION-Array ausgelesen und die Daten in eine Daten gespeichert die später anhand der Session-ID identifiziert wird. Je nach Installation und Konfiguration von PHP wird dieses Datei z.B. als /tmp/sess_5dae76576c5a7e5c4c2a54 gespeichert. Dort liegt sie dann bis sie wieder durch einen session_start-Aufruf geladen wird.

6. Übermitteln der Session-ID

Um im nächsten Skript die richtige Session zu laden müssen wir die Session-ID übermitteln. Es gibt allgemein 3 Wege Daten an ein PHP-Skript zu senden (unabhängig von Sessions): GET, POST und COOKIE. Die Session-ID kann über jeden dieser Wege gesendet werden. Als GET-Variable wird sie in der Form PHPSESSID=... übermittelt, als POST-Variable in der Form <input type="hidden" name="PHPSESSID" value="..." /> und als COOKIE der Form PHPSESSID=.... In der Regel muss man sich entscheiden wie man die Session-ID übermittelt. In URLs könnte sie verwirren, Cookies können deaktiviert sein und nicht überall ist ein Formular vorhanden. Die Funktion session_start versucht ein Cookie zu senden, in der die Session-ID steht. Daher muss diese Funktion relativ früh aufgerufen werden da sie entsprechend den HTTP-Header ergänzt. Es gibt ne Menge an Konfigurationen bezüglich Sessions wie z.B. der Transport der Session-ID. Hier könnte auch die Einstellung session.use_trans_sid interessant sein. Auf jedenfall wir die Session-ID in der Konstante SID abgelegt (durch session_start). Die Konstante hat die Form name=..., wobei name der Variablenname der Session-ID ist (standardmäßig PHPSESSID) und die Punkte die Session-ID entsprechen. Diese Konstante kann somit relativ einfach in URLs verwendet werden.

<?php
echo '<a href="index.php?section=foobar&amp;'.htmlspecialchars(SID).'">Link</a>';
?>

Auch wenn die Konstante SID durch PHP erstellt wird wird ihr Inhalt teils durch Benutzereingaben bestimmt. Wenn die Session-ID den Inhalt " onload="alert(...); enthält hätten wir eine XSS-Lücke. Daher jagen wir die Konstante durch htmlspecialchars. Falls beide Werte getrennt benötigt werden (also Variablenname und Session-ID) kann man die Funktionen session_name und session_id verwenden.

7. Dauer einer inaktiven Session

Die Lebensdauer einer inaktiven Session ist sehr kurz, je nach Konfiguration etwa 30 Minuten. Wenn sie innerhalb dieser Zeit nicht geladen wird wird sie von PHP gelöscht und ist weg. Dies erklärt auch einige Fehlermeldungen in anderen Webanwendung wenn es plötzlich heißt "Ihre Session ist abgelaufen, melden sie sich bitte neu an". Dann hat man sich zuviel Zeit gelassen und PHP hat aufgeräumt und alte Sessions gelöscht. Dies bedeutet insbesondere das man Sessions nicht verwendet um persistente Daten zu speichern. Also bei einem Newssystem sollte man die News nicht in einer Session speichern. Sessions dienen wirklich nur der temporären Übertragen von vielen Daten.

8. Sicherheit von Sessions

Die Inhalte von einer Session können in der Regel nur vom PHP-Skript bestimmt werden, nicht durch den Benutzer. Anhand der Session-ID kann der Benutzer also nicht irgendwie die Session auslesen oder sogar bearbeiten. Daher sind alle Daten in einer Session vertrauenswürdig, es sei denn sie sind natürlich durch Benutzereingaben gefüllt. So braucht man z.B. für ein Login nicht die UserID und das Password speichern, die UserID reicht völlig. Denn wenn die UserID vorhanden ist hat man (hoffentlich) vorher auch geprüft ob der Login gültig ist.

Der Schwachpunkt ist hingegen die Session-ID. Da die Session-ID reicht um die richtige Session zu laden ist sie ein beliebtes Ziel von Crackern sie auszulesen und mitzubenutzen. Ein normaler Admin loggt sich ein und ein Cracker hijacked die Session-ID und benutzt seinen Account mit. Hier muss man sich was einfallen lassen wie z.B. die IP-Adresse mitspeichern aber der Kreativität von Cracker sind keine Grenzen gesetzt.

Da Sessions im Dateisystem normale Dateien sind und in /tmp/ abgelegt werden können sie von jedem PHP-Skript geladen werden oder sogar durch einen einfachen Texteditor auf dem Server. So kann ein Cracker den Inhalt der Session nach belieben verändern bzw. durch ein PHP-Skript auf den Server. Aber wenn der Cracker schon so weit im System ist hat man ganz andere Probleme als eine Session mit komische Daten...

Fragen zum Kapitel

Keine Fragen zum Kapitel vorhanden

Zurück zu Weiter zu
Copyright © bei den OPs von #php.de/QuakeNet Valid XHTML 1.0 Strict Valid CSS!