Web-Sicherheit

Unsichere Deserialisierung

Definition

Unsichere Deserialisierung ist eine Schwachstelle, die entsteht, wenn eine Anwendung Objekte aus Daten wiederherstellt, die ein Angreifer kontrolliert, etwa mit unserialize() in PHP. Die Methoden, die dabei automatisch ausgelöst werden, können zum Löschen von Dateien oder zur Ausführung von Code führen.

Unsichere Deserialisierung, Web-Sicherheit

Serialisieren heißt, strukturierte Daten (ein Array, ein Objekt) in Text zu verwandeln, um sie zu speichern oder zu übertragen; Deserialisieren ist der umgekehrte Vorgang. Problematisch wird es, wenn die wiederherzustellenden Daten von außen kommen: aus einem Cookie, einem Formularfeld, einem URL-Parameter. MITRE führt diese Schwachstelle als CWE-502, „Deserialization of Untrusted Data“; in PHP spricht man auch von PHP Object Injection.

So funktioniert der Angriff in PHP

Ein serialisierter PHP-String beschreibt den Typ dessen, was er enthält. So steht O:4:"User":1:{s:4:"name";s:3:"Bob";} für ein Objekt der Klasse User mit einer Eigenschaft name. Ein Angreifer, der diesen String kontrolliert, kann unserialize() also anweisen, ein Objekt einer beliebigen Klasse zu erzeugen, die auf der Website geladen ist, mit den Werten seiner Wahl.

Gefährlich wird dieses Objekt durch die magischen Methoden, die PHP automatisch aufruft: __wakeup() beim Wiederherstellen, __destruct() beim Zerstören, __toString(), wenn das Objekt als Text verwendet wird. Indem der Angreifer Klassen verkettet, die schon im Code der Website stecken und deren Methoden sich gegenseitig aufrufen, baut er eine Gadget-Kette (POP Chain), die in einer gefährlichen Aktion endet: Löschen einer Datei, Schreiben einer PHP-Datei, Ausführung von Code aus der Ferne.

PHP Object Injection in fünf Schritten: Der Angreifer schickt einen gefälschten serialisierten String in einem Cookie oder Feld, die Anwendung ruft unserialize() auf und baut ein Objekt der gewählten Klasse, PHP führt automatisch die magischen Methoden __wakeup, __destruct oder __toString aus, vorhandene Klassen verketten sich zu einer POP-Gadget-Kette, und am Ende steht das Löschen einer Datei, das Schreiben einer PHP-Datei oder die Ausführung von Code
Es wird kein Code direkt eingeschleust: Der Angreifer missbraucht Klassen, die es auf der Website schon gibt.

Ein Beispiel aus WordPress: GiveWP

Die Schwachstelle CVE-2024-5932 im Spenden-Plugin GiveWP, bis einschließlich Version 3.14.1, erlaubte einem nicht angemeldeten Angreifer, über den Parameter give_title ein PHP-Objekt einzuschleusen. Eine im Plugin vorhandene Gadget-Kette führte zur Ausführung von Code und zum Löschen von Dateien; der veröffentlichte CVSS-3.1-Score liegt bei 10. Unser Beitrag zur PHP Object Injection beschreibt diesen Fall und den Mechanismus im Detail.

Deserialisierung ist für Angreifer auch dann nützlich, wenn sie schon drin sind: Die Hintertür, die 2025 in das Plugin-Portfolio von EssentialPlugin eingebaut wurde, stützte sich auf unserialize, wie unser Beitrag zu Supply-Chain-Angriffen zeigt.

Video: „Insecure Deserialization Attack Explained“ (PwnFunction, auf Englisch)

In WordPress: unserialize und maybe_unserialize

WordPress speichert viele serialisierte Daten, vor allem in der Optionstabelle und in den Metadaten. Zum Zurücklesen dient die Funktion maybe_unserialize(): Sehen die Daten serialisiert aus (is_serialized()), ruft sie unserialize() auf, ohne die erlaubten Klassen einzuschränken. Sie bietet also keinerlei Schutz und darf nie Daten bekommen, die von einem Besucher stammen.

  • Daten als JSON austauschen: Die PHP-Dokumentation empfiehlt json_encode() und json_decode() für alle Daten, die über den Benutzer laufen. JSON erzeugt nie Objekte beliebiger Klassen.
  • Nicht zu viel von allowed_classes erwarten: Diese Option von unserialize() schränkt ein, welche Klassen instanziiert werden, aber das PHP-Handbuch stellt klar, dass nicht vertrauenswürdige Daten unabhängig von ihrem Wert nicht an diese Funktion übergeben werden sollten.
  • Signieren, was hin und her geht: Wenn serialisierte Daten wirklich über den Browser laufen müssen, verhindert eine HMAC-Signatur, die vor jedem Lesen geprüft wird, dass sie manipuliert werden.
  • PHP aktuell halten: Seit PHP 8.0 werden die Metadaten von Phar-Archiven nicht mehr automatisch deserialisiert, was einen Angriffsweg über Dateieinbindung und Wrapper geschlossen hat.

Für Administratoren bleibt das Update der betroffenen Plugins die wichtigste Abwehr, denn die Lücke steckt in deren Code. Eine Web Application Firewall kann verdächtige serialisierte Strings in der Zwischenzeit blockieren, und die Schwachstellenwarnungen von WP Masquerade Pro sagen dir, wenn ein installiertes Plugin zu den betroffenen Versionen gehört. WP Masquerade selbst filtert keine Anfragen.

Weiterlesen

  • Artikel PHP-Deserialisierung und Object Injection erklärt
  • Seite Warnungen bei verwundbaren Plugins

Quellen

  1. MITRE CWE-502: Deserialization of Untrusted Data (externer Link, öffnet in neuem Tab)
  2. PHP Manual: unserialize() (externer Link, öffnet in neuem Tab)
  3. WordPress Developer Resources: maybe_unserialize() (externer Link, öffnet in neuem Tab)
  4. CVE Record: CVE-2024-5932 (externer Link, öffnet in neuem Tab)

Alle Definitionen

WordPress-Sicherheit ohne Lärm

Eine E-Mail, wenn es wichtig ist: neu beobachtete Angriffe, Updates des Plugins und praktische Anleitungen. Kein Spam, Abmeldung mit einem Klick.

Starte kostenlos und wechsle zu Pro, wenn du so weit bist

Die kostenlose Version versteckt WordPress bereits und verschiebt die Anmeldeseite. Pro ergänzt Aliasse, Zwei-Faktor-Authentifizierung und Überwachung.