hackatoll
Zur Lernplattform

Wissen › Insecure Deserialization / PHP Object Injection

Insecure Deserialization / PHP Object Injection

Nutzerdaten (z. B. aus einem Cookie) werden mit unserialize() verarbeitet – ein Angreifer kann damit beliebige interne Objekte erzeugen und deren Magic-Methoden auslösen.

Datenverarbeitung Schweregrad: Hoch
Trainings-Lektion Anmeldung nötig

Lies den Artikel und beantworte am Ende 9 Fragen. Erst wenn alle richtig beantwortet sind, ist die Lektion im Training erledigt.

Zu den Fragen ↓

Serialisierung wandelt ein Objekt in eine speicherbare Zeichenkette um, Deserialisierung baut daraus wieder ein Objekt. Verarbeitet eine Anwendung dabei Daten, die der Angreifer kontrolliert – etwa einen Cookie – mit unserialize(), entscheidet der Angreifer, welche Klasse instanziiert wird und mit welchen Eigenschaften. PHP ruft beim Deserialisieren automatisch bestimmte Magic-Methoden auf (__wakeup(), __destruct()). Enthält eine im Projekt ladbare Klasse in einer solchen Methode eine gefährliche Aktion (Datei schreiben/lesen, Kommandos, DB-Zugriff), lässt sie sich so von außen auslösen – das nennt man PHP Object Injection.

Wie der Angriff funktioniert

Varianten

Objekt über Cookie/Request: Der klassische Fall: unserialize() auf einem Cookie- oder Request-Wert. Weil der Wert angreiferkontrolliert ist, entscheidet nicht die Anwendung, welches Objekt entsteht.
Gadget & POP-Chain: Eine im Projekt ladbare Klasse mit einer gefährlichen Magic-Methode heißt Gadget; mehrere verkettet ergeben eine POP-Chain. Der Fundus ist der gesamte geladene Code (Core, Extensions, Composer-Pakete) – deshalb lässt sich die Gefahr nicht an einer einzelnen Klasse festmachen.
Phar-Deserialisierung: Auch Dateioperationen auf einem phar://-Pfad können im Hintergrund deserialisieren. Daher keine vom Nutzer bestimmten Pfade an Dateifunktionen übergeben.

Beispiel

Der Unterschied ist, WEM die zu deserialisierenden Daten gehören:

// verwundbar: Cookie-Wert direkt deserialisieren
$data = unserialize($_COOKIE['sel']); // Angreifer bestimmt die Objekt-Struktur

// ein 'Gadget' im Projekt, das beim Aufwachen etwas Gefaehrliches tut
class Report {
  public string $datei = '';
  public function __wakeup() { file_put_contents($this->datei, '...'); }
}

// sicher: kein unserialize auf Fremddaten – JSON nutzen
$data = json_decode($_COOKIE['sel'], true);
// oder, wenn unserialize unvermeidbar ist, Klassen verbieten:
$data = unserialize($roh, ['allowed_classes' => false]);

Mögliche Auswirkungen

Selbst prüfen: Wo deserialisiere ich Fremddaten?

Die Abwehr beginnt mit einer Bestandsaufnahme im eigenen Code. Die folgenden Schritte zeigen, wo unsichere Deserialisierung sitzt und wie man sie entschärft – ausschließlich am eigenen Projekt.

1. unserialize() und phar-Pfade finden

Durchsuche den eigenen Code und die Extensions nach unserialize( sowie nach Dateifunktionen mit nutzerbestimmten Pfaden. Jede Fundstelle gegen die Herkunft der Daten prüfen.

2. Stammen die Daten aus dem Request?

Cookies, POST-Felder, URL-Parameter und Uploads gelten als angreiferkontrolliert. Auf solche Daten darf unserialize() nicht angewendet werden.

3. Auf JSON umstellen

Für eigene Persistenz in Cookies/Feldern json_encode/json_decode verwenden. JSON transportiert nur Daten, keine Objekt-Typen – es gibt keine Magic-Methode zum Auslösen.

// statt serialize/unserialize
$cookie = json_encode($data);
$data   = json_decode($roh, true);

4. Unvermeidbares absichern

Ist unserialize() nicht zu vermeiden, mit ['allowed_classes' => false] (oder einer engen Liste) deserialisieren und den Wert zusätzlich per HMAC signieren, damit Manipulation auffällt.

$data = unserialize($roh, ['allowed_classes' => false]);
◆ In TYPO3 beachten

Worauf du in TYPO3 achten musst

In TYPO3 steckt die Gefahr selten im Core-Standard, sondern in Extensions, die eigene Zustände in Cookies oder Feldern serialisieren und ungeprüft zurücklesen. Der Objekt-Graph des gesamten geladenen Projekts (Core, Extensions, Composer-Pakete) steht als Gadget-Fundus zur Verfügung.

unserialize() gehört nicht an Fremddaten

Cookies, Request-Parameter und Uploads sind angreiferkontrolliert. ceselector 4.0.1 z. B. liest einen Plugin-Cookie per unserialize() zurück (CVE-2026-46725) – das reicht für Object Injection, noch bevor irgendeine Prüfung greift.

JSON statt serialize

Für eigene Persistenz in Cookies/Feldern json_encode/json_decode verwenden. JSON transportiert nur Daten, keine Objekt-Typen – es gibt keine Magic-Methode zum Auslösen.

allowed_classes, wenn es sein muss

Ist unserialize() unvermeidbar, mit dem Options-Parameter ['allowed_classes' => false] (oder einer engen Liste) deserialisieren, damit gar keine beliebigen Objekte entstehen. Zusätzlich serialisierte Werte signieren (HMAC), damit Manipulation auffällt.

Schutzmaßnahmen

Trainings-Lektion abschließen

Lektion abschließen: 9 Fragen beantworten

Anmeldung nötig

Diese Lektion gilt im Training erst als erledigt, wenn du alle 9 Fragen zu diesem Artikel richtig beantwortet hast – von leicht bis knifflig. Dafür brauchst du ein Konto, damit dein Fortschritt gespeichert wird.

Anmelden & Fragen beantworten

Interaktiv üben

In der Lernplattform kannst du diese Schwachstellenklasse an einer echten, isolierten TYPO3-Instanz nachvollziehen:

Weiterlesen

Jetzt interaktiv üben →