flawopen.com/Unsichere Deserialisierung/PHP unserialize()
Ist PHP unserialize() für nicht vertrauenswürdige Eingaben sicher?
Übergib keine nicht vertrauenswürdigen Daten an unserialize(), auch nicht mit allowed_classes. PHP kann Objekte wiederherstellen und __unserialize() oder __wakeup() aufrufen; Angreifer könnten verfügbare Anwendungs- oder Autoloader-Klassen ausnutzen. Verwende JSON für nicht vertrauenswürdige Daten. Bei assoziativer Dekodierung werden JSON-Objekte zu Arrays und instanziieren keine Anwendungsklassen mit Magic-Method-Verhalten.
<?php // Cookie content is controlled by the client. $input = $_COOKIE['prefs'] ?? ''; $data = unserialize($input); // Restoring an object may invoke its // __unserialize() or __wakeup() method. // Later object destruction may invoke __destruct(). // The risk depends on available classes, // their serialized state, and reachable behavior.
<?php
$input = $_POST['prefs'] ?? null;
if (!is_string($input)) {
http_response_code(400);
exit;
}
try {
$data = json_decode(
$input,
true,
512,
JSON_THROW_ON_ERROR
);
} catch (JsonException $e) {
http_response_code(400);
exit;
}
if (!is_array($data)) {
http_response_code(400);
exit;
}
// Validate required keys and value types here.
Was eine PHP-Objektinjektionskette voraussetzt
Objektinjektion bedeutet nicht automatisch Codeausführung. Der serialisierte Wert muss eine von PHP auflösbare und laut Optionen erlaubte Klasse benennen; Wiederherstellung oder spätere Nutzung muss außerdem Verhalten mit Sicherheitsauswirkung erreichen. PHP kann beim Wiederherstellen __unserialize() oder __wakeup() aufrufen; __destruct() kann bei der Zerstörung laufen und __toString() nur in einem String-Kontext.
Eine Property-Oriented-Programming-Kette (POP) verbindet Verhalten, das bereits in der Anwendung oder geladenen Abhängigkeiten vorhanden ist. Die Ausnutzbarkeit hängt von realen Klassen, serialisierten Eigenschaften, Aufrufpfad und Laufzeitbedingungen ab. Eine Gadget-Kette für das Ziel muss nachgewiesen werden; unserialize() allein belegt sie nicht.
Warum Stringfilter und allowed_classes keine vollständige Lösung sind
Das Sperren eines Markers wie O:, das Filtern von Klassennamen oder eine Längenbegrenzung validiert PHP-Serialisierung nicht sicher. PHP warnt ausdrücklich davor, nicht vertrauenswürdige Eingaben an unserialize() zu übergeben, unabhängig von allowed_classes. Nicht erlaubte Klassen werden zu __PHP_Incomplete_Class; die Struktur wird trotzdem geparst. Validiere bei vertrauenswürdigen Altdaten die Ergebnisform und begrenze die Tiefe. Nutze für Clientzustand JSON.
Häufige Fragen
Nein. Die Option verhindert die normale Wiederherstellung von Anwendungsklassen; nicht erlaubte Objekte werden zu __PHP_Incomplete_Class. PHP warnt weiterhin vor nicht vertrauenswürdigen Daten für unserialize(), auch mit dieser Option. Nutze sie nur als Defense-in-Depth für vertrauenswürdige Altdaten, validiere das Ergebnis und begrenze max_depth. Laut PHP-Handbuch wirkt die Option nicht auf Enumerationen.
Er kann Datenintegrität für von deiner Anwendung erzeugte Daten bestätigen, wenn der Schlüssel geheim bleibt und hash_equals() die Signatur vor dem Deserialisieren prüft. Ungültige Signaturen müssen vor dem Parsen abgelehnt werden. Ein HMAC verschlüsselt nicht und verhindert keine Wiederholung; ergänze Ablaufzeit oder Nonce, wenn Aktualität nötig ist. Signiere keine beliebigen Nutzerdaten, um sie vertrauenswürdig zu machen.
Alle bergen das allgemeine Risiko, Objekte aus serialisierten Daten wiederherzustellen. Formate, Hooks, Klassenauflösung und Gegenmaßnahmen unterscheiden sich jedoch. Bewerte Runtime und verfügbare Klassen jeweils separat; eine Gadget-Kette einer Plattform gilt nicht automatisch für andere.
Quellen
- PHP-Handbuch — unserialize()
- PHP-Handbuch — Magic Methods
- PHP-Handbuch — JSON-Dekodierung
- PHP-Handbuch — __PHP_Incomplete_Class
- OWASP — PHP-Objektinjektion
- CWE-502 — Deserialisierung nicht vertrauenswürdiger Daten
- Ist Python pickle für nicht vertrauenswürdige Daten sicher?
- Ist Java ObjectInputStream für nicht vertrauenswürdige Daten sicher?