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.
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
- Ein Endpunkt übergibt angreiferkontrollierte Daten direkt an unserialize() – klassisch der Wert eines Cookies, aber auch POST-Felder oder URL-Parameter.
- Der Angreifer baut eine serialisierte Zeichenkette, die ein Objekt einer im Projekt vorhandenen ('ladbaren') Klasse beschreibt, und setzt dessen Eigenschaften frei.
- Beim unserialize() wird das Objekt erzeugt und __wakeup() läuft sofort – noch bevor die Anwendung die Daten überhaupt prüft. __destruct() folgt am Ende des Requests.
- Nützliche Klassen mit gefährlichen Magic-Methoden heißen 'Gadgets'; mehrere verkettet ergeben eine 'POP-Chain' (Property-Oriented Programming) bis hin zu RCE.
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
- Abfluss interner Daten: ein Gadget liest/schreibt Dateien und legt Geheimnisse an erreichbarer Stelle ab.
- Manipulation von Programmzustand: beliebige Objekte mit angreifergewählten Eigenschaften gelangen in den Ablauf.
- Remote Code Execution: über eine passende POP-Chain lässt sich im schlimmsten Fall beliebiger Code ausführen.
- Der Einstieg braucht keine Anmeldung, wenn der verwundbare Endpunkt öffentlich ist (z. B. ein FE-Plugin-Cookie).
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
- Niemals unserialize() auf Daten anwenden, die aus Request/Cookie/Upload stammen.
- Für eigene Persistenz JSON nutzen (json_encode/json_decode) statt serialize/unserialize.
- Wenn unserialize() unvermeidbar ist: ['allowed_classes' => false] setzen und den Wert zusätzlich per HMAC signieren.
- Core/Extensions aktuell halten (hier: ceselector ≥ 4.0.2 bzw. der jeweilige Security-Fix-Branch).
Interaktiv üben
In der Lernplattform kannst du diese Schwachstellenklasse an einer echten, isolierten TYPO3-Instanz nachvollziehen: