Session Fixation

Sessions und Sicherheit ist ein sehr anspruchsvolles Thema und so überrascht es nicht, dass Sessions ein häufiges Ziel von Angriffen sind. Die meisten Angriffe auf diesem Bereich beinhalten die Personifizierung, da der Angreifer versucht an die Session-Daten eines anderen Users zu gelangen.

Die entscheidende Information für Angreifer in diesem Bereich ist die Session ID, da diese für jeden personalisierten Angriff benötigt wird.

Es gibt drei übliche Wege um sich eine Session ID zu beschaffen:

  • Vorhersage
  • Beschaffung
  • Fixierung

Die Vorhersage beruht auf dem Versuch, eine vergebene Session ID zu erraten. Mit dem in PHP eingebauten Session-System ist die Session ID ein extrem zufälliger Wert, der nur sehr unwahrscheinlich vorhergesagt werden kann. Hier liegt die geringste Chance auf einen Schwachpunkt.

Die Beschaffung, das Stehlen, einer Session ID ist der wohl häufigste Angriff und es gibt eine Vielzahl von Angriffsmöglichkeiten. Da die Session ID üblicherweise in einem Cookie oder per GET übergeben wird, gehen die Angriffsszenarien in die Richtung, diese Arten des Datentransfers abzufangen. Es gab (und gibt) einige Lücken in Browsern, doch sind es weniger Lücken bezüglich Cookies als hinsichtlich des Get-Strings. Insofern erscheint es ratsam, die Session ID in einem Cookie abzulegen.

Die Fixierung ist die einfachste Methode eine Session ID zu erhalten. Auch wenn es nicht schwierig ist, sich dagegen zu verteidigen: Wenn das Session-System nichts anderes als session_start() aufruft ist man verwundbar.

Um dies zu demonstieren, ein Beispiel:

Zitat<?php
session_start();
if (!isset($_SESSION['visits']))
{
$_SESSION['visits'] = 1;
}
else
{
$_SESSION['visits']++;
}
echo $_SESSION['visits'];
?>

Beim ersten Aufruf dieses Skriptes sollte eine 1 zu sehen sein, bei jedem weiteren erhöht sich der Wert jeweils um 1.

Um nun die Session-Fixation zu demonstrieren, rufen man mit einem anderem Browser (oder gar mit einem anderen Rechner) das gleiche Skript mit dem GET-String ?PHPSESSID=1234 auf. Es fällt auf, dass beim ersten Aufruf keine 1 angezeigt wird, wohl aber eine andere Zahl. Man führt nun die Session fort, die woanders begonnen wurde. Warum kann dies ein Problem darstellen? Die meisten Angriffe auf diesem Gebiet leiten den User zu einer Seite weiter oder nutzen einen Protokoll-Redirect, wobei versucht wird, die vorbereitete Session-ID mitzuschicken. Da der Angreifer bei dieser Methode die Session-ID vom Angreifer vorgegeben wird, kann er diese nun nutzen, um jederzeit Angriffe hierüber zu starten.
Ein derart einfacher Angriff kann ebenso einfach abgewehrt werden. Solange keine aktive Session mit einer gültigen Session-ID mit dem aktuellen User verbunden ist, lässt man diese einfach regenerieren:

Zitat<?php
session_start();
if (!isset($_SESSION['initiated']))
{
session_regenerate_id();
$_SESSION['initiated'] = true;
}
?>

So einfach diese Abwehr auch ist, ebenso leicht kann sie wiederum umgangen werden: Etwa wenn ein Angreifer sich die Mühe macht, erst selbst eine gültige Session-ID zu erzeugen und diese dann gezielt weiter zu geben.

Wenn es nun darum geht, sich gegen diese Angriffsform zu verteidigen, sollte man daran denken, dass Session-Angriffe nur dann wirklich sinnvoll sind, wenn ein Benutzer sich angemeldet hat oder sonst auf eine bestimmte Art und Weise besondere Rechte auf der Webseite erlangt. Wenn also der Ansatz zur Regenerierung der Session als Verteidigung weiter verfolgt wird, dann insofern, als dass er immer dann zum Einsatz kommt, sobald sich die Rechte eines Users innerhalb der Anwendung in irgendeiner Form verändern.


Netzwerke