PHP2Shell: Was Admins über die kritischen PHP-Lücken wissen
Sie befinden sich: Home > Webmaster News
Am 20. Oktober 2026 hat das PHP-Sicherheitsteam etwas Ungewöhnliches getan: Es hat ein Sicherheitsupdate einen Tag vorher öffentlich angekündigt. Der Grund war ein Leak. Details zu zwei kritischen Lücken im PHP-Kern waren öffentlich, bevor ein Patch existierte. Unter dem Namen PHP2Shell laufen seither die Schwachstellen CVE-2026-109618 und CVE-2026-109619, beide mit CVSS 9.2 bewertet. Am 21. Oktober gegen 15:35 Uhr deutscher Zeit, knapp eine halbe Stunde vor dem angekündigten Termin, hat PHP die Updates 8.5.12, 8.4.27, 8.3.36 und 8.2.35 veröffentlicht. Wer PHP im Web betreibt, sollte sie heute noch einspielen.
Dieser Artikel trennt, was PHP selbst bestätigt hat und was aus Leaks und Analysen von Sicherheitsfirmen stammt. Er erklärt, wer betroffen ist, warum ein WordPress-Update hier nichts nützt und welche Notbehelfe weniger taugen, als sie versprechen. Am Ende stehen eine Checkliste für den Server und die Fragen, die gerade überall auftauchen.
Die Abschnitte folgen der Reihenfolge, in der Sie handeln sollten. Zuerst kommt die Lage, dann die Frage, wen PHP2Shell trifft. Danach folgen das Update, die Übergangslösungen und die Suche nach Spuren eines Einbruchs.
Was zu PHP2Shell offiziell feststeht
Die einzige Primärquelle vor dem Release war eine kurze Meldung auf php.net vom 20. Oktober. Das Sicherheitsteam nennt darin zwei kritische Schwachstellen, beide mit CVSS v4.0 9.2 bewertet. Das Release war für Mittwoch, den 21. Oktober, um 14:00 UTC geplant. Das entspricht 16 Uhr deutscher Zeit. PHP behielt sich vor, früher zu veröffentlichen, falls Details öffentlich würden oder Angriffe auftauchten. Betroffene Versionen, gefixte Versionen und alle Einzelheiten sollten erst mit dem Release folgen.
Auffällig ist, was in der Meldung fehlt. CVE-Nummern nennt PHP dort nicht. Die Kennungen CVE-2026-109618 und CVE-2026-109619 standen bereits im geleakten Beitrag. Breit bekannt wurden sie durch den Sicherheitsforscher Kevin Beaumont. CERT-EU und das BSI haben sie in ihre Warnungen übernommen. In der amerikanischen Schwachstellendatenbank NVD und bei CVE.org gab es am Mittag des 21. Oktober noch keinen öffentlichen Eintrag.
Mit dem Release hat PHP nachgeliefert. Das Sicherheitsadvisory auf php.net nennt beide CVE-Nummern, beschreibt die Fehler und listet Notmaßnahmen. Die technischen Details stehen in zwei Advisories auf GitHub, GHSA-w8hw-w9fx-j79w und GHSA-6wmf-4rv5-p3rp. Beide Lücken erlauben laut PHP Codeausführung ohne Anmeldung, und zwar mit den Rechten des Webserver-Benutzers. Betroffen sind alle Installationen, die Webanfragen bedienen: PHP-FPM, Apache mit mod_php, php-cgi, FrankenPHP und LiteSpeed. Das höchste Risiko sieht PHP bei mod_php. Dort gibt es einen vorgeführten Exploit, der greift, bevor irgendein Anwendungscode läuft.
Die Releases 8.5.12 und 8.4.27 bringen zusätzlich die regulären Bugfixes mit, die ohnehin für den 22. Oktober geplant waren. Im Changelog steht deshalb noch dieses Datum.
Die folgende Übersicht zeigt, wie belastbar die einzelnen Angaben sind. Der Stand bezieht sich auf die Zeit vor dem Release, die letzte Spalte auf das, was PHP danach geliefert hat.
| Angabe |
Quelle vor dem Release |
Nach dem Release |
| Zwei kritische Lücken, je CVSS v4.0 9.2 |
php.net, bestätigt |
bestätigt, Vektor im Advisory |
| CVE-2026-109618 und CVE-2026-109619 |
Leak, Kevin Beaumont, CERT-EU, BSI |
bestätigt, PHP nennt beide |
| Betroffen ab PHP 5 beziehungsweise 5.4 |
CERT-EU, Sansec, Banner des Exploit-Tools |
alle Versionen vor den neuen Releases; eine Untergrenze nennt PHP nicht |
| Fehler in der Upload- und Multipart-Verarbeitung |
Leak-Analysen, teils widerrufen |
teilweise: Upload-Fortschritt ist einer von mehreren Wegen, Kern sind Speichermangel und veralteter Zustand |
| Fix in 8.5.12, 8.4.27, 8.3.36 und 8.2.35 |
Kevin Beaumont, Tenable |
bestätigt |
| Angriffe schon vor dem Patch |
Cloudflare, RUS-CERT; BSI: nicht bestätigt |
PHP: Exploit gegen mod_php vorgeführt, zu echten Angriffen keine Angabe |
Wie PHP2Shell vor dem Patch öffentlich wurde
Normalerweise läuft eine Sicherheitslücke so ab: Jemand meldet sie vertraulich, das Projekt baut den Fix, und am Tag des Releases erfahren alle gleichzeitig davon. Bei PHP2Shell ist diese Ordnung zerbrochen. Die Zeitleiste zeigt, wie schnell das ging. Alle Zeiten stehen in UTC, die deutsche Zeit liegt zwei Stunden später.
Zeitleiste PHP2Shell (UTC)
- 20.10., 15:20: Ein Beitrag auf Hacker News kündigt zwei PHP-Lücken mit Remote-Code-Execution an. Als Termin nennt er noch Donnerstag, den 22. Oktober. Der Beitrag wird später gelöscht.
- 20.10., 16:39: Kevin Beaumont schreibt, jemand habe CVE-2026-109618 und CVE-2026-109619 vor dem Patch geleakt.
- 20.10., abends: watchTowr bestätigt gegenüber BleepingComputer, dass die Lücken echt sind. php.net zieht das Release auf den nächsten Tag vor und kündigt es öffentlich an. CERT-EU veröffentlicht das Advisory 2026-018.
- 21.10., 02:13: PHP-Kernentwicklerin Gina Peter Banyard schreibt, die einzige Abhilfe sei das Update.
- 21.10., 07:00: Das RUS-CERT der Universität Stuttgart veröffentlicht seine Warnung. Im Lauf des Tages folgt das BSI mit einem Sicherheitshinweis der Stufe 3 von 4 (Orange).
- 21.10., 07:43: Cloudflare-CTO Dane Knecht meldet erste Angriffe und neue WAF-Regeln, ausdrücklich nur als Übergangslösung.
- 21.10., 08:48: Laut Sansec warnt die PHP Foundation, dass das Remi-Repository für RHEL-Systeme an diesem Tag keine Updates liefert.
- 21.10., 10:35: In den Niederlanden gehen das Technikportal Tweakers, das Parlament, das nationale Cyber-Sicherheitszentrum NCSC und Security.NL vorsorglich vom Netz.
- 21.10., 12:05: Das RUS-CERT meldet, es habe einen öffentlich verfügbaren Exploit auf einem Testsystem erfolgreich nachvollzogen.
- 21.10., 13:34: PHP veröffentlicht die beiden Advisories auf GitHub, kurz darauf PHP 8.5.12, 8.4.27, 8.3.36 und 8.2.35 samt Sicherheitshinweis auf php.net. Angekündigt war 14:00 UTC.
Der Name PHP2Shell spielt auf Log4Shell an, die Lücke in der Java-Bibliothek Log4j vom Dezember 2021. Das BSI zieht diesen Vergleich ausdrücklich. Er trifft den Kern: eine Komponente, die fast überall steckt, und ein Angriff ohne Anmeldung.
Wer von PHP2Shell betroffen ist
PHP2Shell steckt im PHP-Interpreter selbst, das hat das Release bestätigt. Nicht in WordPress, nicht in Laravel, nicht in einem Plugin. Damit ist jede Anwendung betroffen, die auf einer verwundbaren PHP-Version läuft. Das BSI nennt als Beispiele WordPress, Drupal, TYPO3, Joomla, Magento, Nextcloud, pfSense und OPNsense. Die letzten beiden sind Firewall-Systeme. Auch Geräte, deren Weboberfläche mit PHP gebaut ist, gehören also auf Ihre Liste. Das Advisory spricht ausdrücklich von Installationen, die Webanfragen bedienen.
Vor dem Release gab es zu den Versionen nur Angaben Dritter. CERT-EU spricht von allen Versionen ab PHP 5 und verweist dafür auf einen Beitrag von Kevin Beaumont. Sansec und das Banner des geleakten Exploit-Tools nennen PHP 5.4. PHP selbst nennt keine Untergrenze. Laut Advisory sind alle Versionen vor den neuen Releases betroffen. Für PHP 7.4, 8.0 und 8.1 hat das Sicherheitsteam wegen der Schwere ausnahmsweise minimale Patches für den Quellcode bereitgestellt, gedacht für alle, die PHP selbst kompilieren. Neue Releases gibt es für diese Zweige nicht.
Für die Planung hilft ein Blick auf den Supportstatus der PHP-Zweige. Er entscheidet, ob es überhaupt einen offiziellen Fix geben kann.
| Zweig |
Sicherheitsupdates bis |
Fix für PHP2Shell |
| PHP 8.5 |
31.12.2029 |
PHP 8.5.12 |
| PHP 8.4 |
31.12.2028 |
PHP 8.4.27 |
| PHP 8.3 |
31.12.2027 |
PHP 8.3.36 |
| PHP 8.2 |
31.12.2026 |
PHP 8.2.35 |
| PHP 8.1 und älter |
ausgelaufen, 8.1 am 31.12.2025 |
kein Release; Quellcode-Patches für 7.4, 8.0 und 8.1, sonst Distribution fragen |
Wer PHP 8.1 oder älter betreibt, hat das eigentliche Problem nicht erst seit gestern. Vom PHP-Projekt kommt für diese Zweige kein fertiges Update, nur die genannten Quellcode-Patches. Eine Chance gibt es trotzdem: Linux-Distributionen mit Langzeitpflege portieren Sicherheitsfixes oft in ihre eigenen Pakete zurück, auch für Zweige, die bei PHP längst ausgelaufen sind. Ob und wann das passiert, steht im Sicherheitshinweis der jeweiligen Distribution. Ohne einen solchen Hinweis bleibt nur, das System abzuschotten und die Migration vorzuziehen.
Ein zweiter Punkt betrifft genau diese Pakete. Debian, Ubuntu oder Red Hat übernehmen den Fix oft, ohne die PHP-Versionsnummer anzuheben. Ein Paket kann also nach einer alten Version aussehen und trotzdem sicher sein. Umgekehrt sagt eine aktuelle Nummer im Hosting-Panel nichts darüber, ob der Build schon gepatcht ist. Maßgeblich ist das Changelog des Pakets oder die Auskunft des Hosters. PHP hat Distributionen und LTS-Anbieter vorab mit den Patches versorgt, deren Pakete sollten also schnell folgen.
Was technisch hinter PHP2Shell steckt
Mit dem Release ist die Ursache von PHP2Shell offiziell, und sie ist anders gelagert, als die meisten Analysen vom Vormittag vermutet hatten. Beide Lücken hängen am Lebenszyklus eines Requests. Es geht um Speicher, der nur halb vorbereitet ist oder schon wieder freigegeben wurde.
CVE-2026-109618 nutzt Speichermangel als Hebel. Reicht der Speicher nicht, bricht PHP einen Request bisher mit einem harten Sprung ab, technisch über longjmp(). Trifft das einen Moment, in dem Request-Daten erst halb angelegt sind, bleibt ein ungültiger Zustand zurück. Das anschließende Aufräumen behandelt ihn als gültig. Den Speichermangel kann ein Angreifer gezielt auslösen, etwa mit Multipart-Requests, die viel mehr Speicher verbrauchen, als ihre Größe vermuten lässt. Bei Apache mit mod_php passiert das komplett, bevor Ihre Anwendung startet. Gegen diese Umgebung hat PHP die Codeausführung mit Standardwerten nachgewiesen. PHP-FPM beendet den Worker, wenn der Start eines Requests scheitert. Laut Quellcode-Analyse ist FPM trotzdem anfällig, ein vollständiger Exploit wurde dort aber nicht vorgeführt. FrankenPHP verhält sich nach Einschätzung von PHP wie mod_php.
CVE-2026-109619 nutzt veralteten Zustand im Worker. Ein PHP-Worker bearbeitet nacheinander viele Requests. Dabei merkt er sich in globalen Variablen Zeiger auf Speicher, der dem gerade laufenden Request gehört. Bricht dieser Request mit einem fatalen Fehler ab, wird so ein Zeiger nicht immer zurückgesetzt. Der nächste Request im selben Worker greift dann vor seiner eigentlichen Initialisierung auf bereits freigegebenen Speicher zu. Das ist ein Use-after-Free, verteilt auf zwei Requests.
Zwei Wege dafür sind bestätigt. Der erste betrifft nur PHP 8.5: Bei eingeschalteten fatal_error_backtraces bleibt der Backtrace eines fatalen Fehlers stehen. Das ist laut PHP der stärkste nachgewiesene Fall. Der zweite läuft über den Upload-Fortschritt in der Session. Ihn hat PHP gegen mod_php und gegen FPM nachgewiesen, bei FPM allerdings nur zusammen mit einer passenden Operation der Anwendung. Als Auslöser genügen neben fatalen Fehlern auch Warnungen, etwa durch veraltete oder ungültige INI-Einstellungen, die pro Verzeichnis gesetzt werden.
Wenn ein Browser ein Formular mit Datei abschickt, nutzt er einen Request vom Typ multipart/form-data. PHP zerlegt diesen Body selbst, bevor auch nur eine Zeile Ihres Codes läuft. Erst danach stehen $_POST und $_FILES bereit. Wie dieser Ablauf aus Sicht der Anwendung aussieht, zeigt das Tutorial zum sicheren Datei-Upload in PHP. Genau in diesem Teil davor, den Ihr Code nie sieht, sitzt ein Großteil des Problems.
Die meistgenannte Spur vom Vormittag führte zu session.upload_progress. Die Funktion schreibt den Fortschritt eines Uploads in die Session, damit eine Seite einen Ladebalken anzeigen kann. Es gibt sie seit PHP 5.4, und sie ist standardmäßig eingeschaltet. Ausgelöst wird sie über ein Formularfeld mit dem Namen PHP_SESSION_UPLOAD_PROGRESS, ein Aufruf von session_start() ist dafür nicht nötig. Wie Sessions grundsätzlich funktionieren, erklärt das Tutorial zu session_start().
Zuverlässig ist ein Angriff über PHP2Shell nicht. Erfolg und Übertragbarkeit hängen laut PHP vom Build, den Erweiterungen, dem vorgeschalteten Webserver und der Anordnung des Speichers ab. Mehrere Worker senken die Trefferquote je Request, verhindern den Angriff aber nicht.
Wie wackelig die frühen Analysen waren, zeigt ein Beispiel. Ein am Morgen des 21. Oktober viel geteiltes Write-up beschrieb den Fehler als Use-after-Free im Upload-Handler php_session_rfc1867_callback. Sein Autor hat diesen Pfad wenige Stunden später selbst als nicht gangbar markiert. Der Entwickler Mattias Geniar hat die Korrektur in seinem Blog dokumentiert. Der Upload-Fortschritt spielt zwar tatsächlich eine Rolle, aber auf ganz anderem Weg. Wer seine Notmaßnahmen auf frühe Analysen gebaut hat, sollte sie jetzt mit dem Advisory abgleichen.
Auch die zweite Behauptung aus dem Leak hat sich bestätigt. Es gibt einen Weg über die Multipart-Verarbeitung, der ohne Upload-Fortschritt auskommt: CVE-2026-109618 braucht ihn gar nicht. Hier spielt eine Neuerung aus PHP 8.4 hinein: Mit request_parse_body() können Anwendungen auch PUT- und PATCH-Requests im Multipart-Format zerlegen lassen. Wer am Webserver nur POST filtert, deckt solche Anwendungen nicht ab.
Daraus folgt der wichtigste Punkt des ganzen Falls. Zumindest unter mod_php bekommt Ihre Anwendung den Angriff gar nicht zu sehen. Login-Prüfung, CSRF-Token, Wartungsmodus und Sicherheits-Plugins laufen erst, wenn PHP den Body längst verarbeitet hat. Ob eine Seite überhaupt ein Upload-Formular hat, spielt keine Rolle. PHP zerlegt jeden Multipart-POST, den der Webserver an ein PHP-Skript durchreicht.
Wie gefährlich PHP2Shell wirklich ist
CVSS 9.2 von 10 ist die offizielle Bewertung. Der Leak-Beitrag und der Chef von watchTowr sprachen von 10.0. Den Unterschied erklärt der Vektor, den PHP mit dem Release veröffentlicht hat. Ein Angreifer braucht weder Zugangsdaten noch den Klick eines Nutzers. Der Angriff gilt aber als anspruchsvoll und an Bedingungen geknüpft, zum Beispiel müssen zwei Requests beim selben Worker landen. Für Sie ändert das wenig. Ein PHP-Server, der aus dem Internet erreichbar ist, genügt als Ziel.
Bei der Frage, ob schon angegriffen wird, widersprechen sich die Quellen. Das liegt vor allem an der Uhrzeit. watchTowr schrieb am Vormittag des 21. Oktober, Angriffe seien nicht bekannt. Huntress hatte am Vortag ebenfalls keine Ausnutzung bei seinen Partnern gesehen. Cloudflare-CTO Dane Knecht meldete dagegen schon um 07:43 UTC erste Angriffe. Das RUS-CERT schrieb um 14:05 Uhr deutscher Zeit, es habe einen öffentlichen Exploit auf einem Testsystem nachvollzogen, und Angriffe seien bereits beobachtet worden. Das BSI hielt am selben Tag fest, bestätigte Ausnutzungen seien noch nicht bekannt. Belege für Angriffe hat bislang keine dieser Stellen veröffentlicht. PHP äußert sich im Advisory nicht zu Angriffen im Netz, beschreibt aber einen funktionierenden Exploit gegen mod_php.
Ich halte die Unterschiede für Zeitstempel, nicht für echte Widersprüche. Die Lage hat sich im Lauf des 21. Oktober verschärft, und mit dem Release ändert sie sich noch einmal. Das BSI hält eine breite Ausnutzung innerhalb weniger Stunden nach Erscheinen der Patches für wahrscheinlich. Sansec rechnet sogar mit Massenangriffen binnen 15 Minuten nach dem Release. Angreifer vergleichen den alten mit dem neuen Quellcode und sehen dann genau, wo der Fehler saß. Wer am Abend des Release-Tages noch ungepatcht ist, steht ohne Schutz da.
Eine Warnung gehört an diese Stelle. Auf GitHub und in Foren kursieren Skripte, die angeblich prüfen, ob ein Server verwundbar ist. Tenable warnt, dass ungeprüfter Exploit-Code mitunter selbst Schadsoftware enthält. heise berichtet von einem kursierenden Exploit, der sich im Labor nicht nachstellen ließ und nur auf den Webserver LiteSpeed zielt. Testen Sie Ihre Server nicht mit solchem Code. Das Update ist schneller eingespielt als ein fremdes Skript geprüft.
PHP2Shell beheben: was jetzt zu tun ist
Die kurze Antwort lautet: PHP aktualisieren und danach alle PHP-Prozesse neu starten. Die lange Antwort steckt in den Details, an denen Updates in der Praxis scheitern. Gehen Sie die Punkte der Reihe nach durch.
1
Alle PHP-Installationen finden.
Gemeint sind nicht nur die Webserver, die Sie täglich sehen. Dazu gehören Staging-Systeme, vergessene Marketing-Seiten auf Subdomains, Docker-Images, Hosting-Panels wie Plesk oder cPanel und Geräte mit PHP-Weboberfläche. Kommandozeile und Webserver nutzen oft unterschiedliche PHP-Versionen. Wie Sie die Version im Web zuverlässig auslesen, zeigt das Tutorial zu phpversion().
2
Das Update einspielen, Internet-Server zuerst.
Aktualisieren Sie auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35. Bei Paketen Ihrer Distribution zählt deren Sicherheitshinweis, nicht die Versionsnummer. Aufpassen müssen Nutzer des Remi-Repositorys unter RHEL, Alma oder Rocky. PHP warnt ausdrücklich, dass dieses ehrenamtlich gepflegte Repository am 21. Oktober keine Updates liefert, und rät zu den Paketen der Distribution oder zum Bau aus dem Quellcode.
3
Jeden PHP-Prozess neu starten.
Ein Paket-Update tauscht die Dateien auf der Platte aus. Laufende Prozesse arbeiten aber mit dem alten Programm im Speicher weiter. Starten Sie PHP-FPM neu, bei mod_php den Apache. Vergessen Sie die langlebigen Prozesse nicht: Queue-Worker, Laravel Horizon, Octane, Reverb, den Scheduler und alles, was Supervisor am Leben hält. FrankenPHP bringt PHP in seinem eigenen Programm mit. Dort brauchen Sie einen neuen FrankenPHP-Build, ein Neustart allein genügt nicht.
4
Container neu bauen.
Ein Update auf dem Host ändert nichts an laufenden Containern. Jedes Image trägt seinen eigenen PHP-Build. Ziehen Sie das gepatchte Basis-Image, bauen Sie Ihr Image neu und rollen Sie es aus. Wie ein PHP-Container aufgebaut ist, zeigt das Tutorial PHP mit Docker.
5
Beim Hoster nachfragen.
Auf Shared Hosting und Managed Servern spielt der Anbieter das Update ein. Fragen Sie konkret, ob der Build für Ihre Domain den Fix für CVE-2026-109618 und CVE-2026-109619 enthält. Eine neue Versionsnummer im Panel auszuwählen, garantiert noch keinen gepatchten Build.
6
Alte Zweige vom Netz nehmen.
Für PHP 8.1 und älter gibt es kein fertiges Update von PHP, nur Quellcode-Patches für 7.4, 8.0 und 8.1. Solange auch Ihre Distribution keinen Fix liefert, gehört ein solches System nicht offen ins Internet. CERT-EU, das BSI und das RUS-CERT raten übereinstimmend dazu, betroffene Anwendungen vom Netz zu trennen oder den Zugriff auf bekannte Adressen und VPN zu beschränken.
7
Logs sichern, bevor Sie aufräumen.
Ein Deployment oder die nächste Logrotation löscht genau die Spuren, die Sie später brauchen. Kopieren Sie Webserver-, PHP-FPM- und Systemlogs ab dem 20. Oktober an einen sicheren Ort, bevor Sie das Update einspielen.
Für die Bestandsaufnahme auf einem Linux-Server genügen wenige Befehle. Der Paketname hängt von Distribution und Zweig ab, das Beispiel nutzt PHP 8.3 unter Debian oder Ubuntu.
# Version der Kommandozeile
php -v
# Version, die PHP-FPM wirklich nutzt
php-fpm8.3 -v
# installierte PHP-Pakete (Debian, Ubuntu)
dpkg -l | grep -i php
# installierte PHP-Pakete (RHEL, Alma, Rocky)
rpm -qa | grep -i php
# angebotene Paketversion prüfen
apt-cache policy php8.3-fpm
# nach dem Update neu starten
sudo systemctl restart php8.3-fpm
Vergleichen Sie die angezeigte Paketversion mit dem Sicherheitshinweis Ihrer Distribution. Erst wenn beide zusammenpassen und der Dienst neu gestartet ist, ist der Server gepatcht. Ob er auch sauber ist, klärt erst die Spurensuche weiter unten.
Das Update gegen PHP2Shell bringt eine Verhaltensänderung mit. PHP bricht bei Speichermangel nicht mehr sofort ab, sondern erst am nächsten sicheren Punkt der Ausführung. Erreicht der Verbrauch eine zweite, höhere Schwelle, beendet sich der Prozess hart. Skripte, die regelmäßig am memory_limit kratzen, können sich danach etwas anders verhalten. Ein Blick ins Fehlerlog in den ersten Tagen lohnt sich.
Übergangsmaßnahmen und ihre Grenzen
Wer PHP2Shell nicht sofort per Update schließen kann, findet im Advisory für jede der beiden Lücken eigene Notmaßnahmen. PHP schreibt selbst dazu, dass sie einzelne Angriffswege verkleinern, eine Installation aber nicht sicher machen. Gina Peter Banyard aus dem PHP-Kernteam nannte das Update schon in der Nacht die einzige Abhilfe. Joe Ferguson, Release-Manager von PHP 8.6, sagte es noch knapper: Ini-Einstellungen retten Sie nicht. Und das RUS-CERT warnte vor dem Release, die damals kursierenden Maßnahmen ließen sich umgehen.
Gegen CVE-2026-109619 hilft vor allem, den Upload-Fortschritt abzuschalten. Auf PHP 8.5 kommt fatal_error_backtraces dazu. Gegen CVE-2026-109618 nennt PHP drei Stellschrauben: ein fest vorgegebenes memory_limit = -1, ein kleines post_max_size und Grenzen am Webserver. Für Anwendungen ohne Datei-Upload empfiehlt PHP 8M, mit Upload 32M, wobei upload_max_filesize darunter bleiben muss. Im FPM-Pool sieht das so aus:
; FPM-Pool, z. B. /etc/php/8.3/fpm/pool.d/www.conf
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
; nur PHP 8.5
php_admin_flag[fatal_error_backtraces] = off
Unter Apache mit mod_php gehören dieselben Werte als php_admin_value und php_admin_flag in die Server- oder VirtualHost-Konfiguration. Danach müssen Sie jeden Worker neu starten. Mit ini_set() im Skript oder einer .user.ini lässt sich nichts davon lösen, darauf weist PHP ausdrücklich hin. Beide greifen erst, wenn PHP den Request schon zerlegt hat. Welche Einstellungen sich zur Laufzeit ändern lassen und welche nicht, erklärt das Tutorial zu ini_set().
Das unbegrenzte Speicherlimit hat eine Kehrseite. Ohne Grenze kann ein einzelner Request den ganzen Arbeitsspeicher belegen. PHP empfiehlt deshalb eine Grenze über Container oder cgroup, am besten pro Worker, damit nicht gleich der ganze Pool stirbt. Die Kernel-Grenzen RLIMIT_AS und RLIMIT_DATA sind dagegen tabu. Sie lösen genau den Speicherfehler aus, über den der Angriff läuft. Ein Restrisiko bleibt auch so, denn das Betriebssystem kann selbst einmal keinen Speicher mehr hergeben.
Der Streit vom Vormittag, ob der Schalter für den Upload-Fortschritt etwas bringt, ist damit entschieden. Er blockiert die nachgewiesenen Session-Wege von CVE-2026-109619, gegen andere Varianten hilft er nicht. PHP empfiehlt sogar, die Funktion auch nach dem Update ausgeschaltet zu lassen, wenn Sie sie nicht brauchen. Das Advisory nennt sie kaum genutzt und kaum getestet. Dem schließe ich mich an.
Ein unscheinbarer Punkt betrifft INI-Einstellungen, die pro Verzeichnis oder pro Request gesetzt werden. Unter mod_php wendet PHP die php_value-Zeilen aus einer .htaccess vor dem Start des Requests an. Bei FPM gilt dasselbe für PHP_VALUE-Parameter, die nginx mitschickt. Erzeugt eine dieser Einstellungen eine Warnung oder Deprecation, kann schon diese Meldung den veralteten Zustand anfassen. Typische Kandidaten sind laut Advisory veraltete Direktiven wie auto_detect_line_endings oder ungültige Werte für memory_limit und date.timezone. Räumen Sie solche Zeilen auf.
Wer auf Leistung verzichten kann, lässt jeden FPM-Worker mit pm.max_requests = 1 nur einen einzigen Request bearbeiten. Dann gibt es keinen Folge-Request, der auf veralteten Zustand treffen kann. Auch das nennt PHP als Möglichkeit.
Bleibt der Webserver. Braucht Ihre Anwendung keine Multipart-Formulare, empfiehlt PHP, solche Requests schon dort abzuweisen. Das hat einen deutlichen Preis. Datei-Uploads funktionieren danach nicht mehr. Das trifft die WordPress-Mediathek und Upload-Felder in Livewire oder Filament. Auch Contact Form 7 fällt aus, denn es schickt seine Formulare selbst ohne Dateifeld als Multipart. Unter nginx gehört die map in den http-Kontext, die Abfrage oben in jeden server-Block:
# http-Kontext, z. B. /etc/nginx/conf.d/
map $http_content_type $block_multipart {
default 0;
"~*multipart" 1;
}
# oben in jeden server-Block mit PHP
if ($block_multipart) {
return 403;
}
Unter Apache 2.4 steht die Sperre am besten im VirtualHost. Notfalls funktioniert sie auch in der .htaccess, dort oberhalb der WordPress-Regeln:
<If "req('Content-Type') =~ /multipart/i">
Require all denied
</If>
Schreiben Sie req('Content-Type') genau so. Die naheliegende Variable %{CONTENT_TYPE} meint in Apache-Ausdrücken den Typ der Antwort, die Sperre ließe Multipart dann durch. Verbreitet ist auch eine Variante mit mod_rewrite. Schmalbach hat beobachtet, dass ein Unterordner mit eigener .htaccess sie aushebeln kann. Ob die Sperre greift, prüfen Sie von außen. Erwartet wird die Antwort 403:
curl -sS -o /dev/null -w "%{http_code}\n" \
-F test=1 https://www.example.com/
Zwei Fallen sind dabei verbreitet. Die Regel muss in jedem Server-Block stehen, der an PHP weiterreicht, auch im Default- und Catch-all-Block. Angreifer sprechen gern direkt die IP-Adresse des Servers an. Und sie muss für alle HTTP-Methoden gelten, nicht nur für POST. Wiederholen Sie den Test deshalb mit -X PUT gegen eine PHP-Datei und mit --resolve direkt gegen die IP-Adresse des Servers. Die Sperre ist eine zusätzliche Hürde für die Stunden bis zum Update. Ein Grund, das Update aufzuschieben, ist sie nicht. Wer Uploads braucht, kann am Webserver wenigstens die Größe des Bodys, die Zahl der Felder und Teile sowie die Header begrenzen. Diese Grenzen müssen laut PHP auch für Requests ohne verwertbare Längenangabe gelten.
Am zuverlässigsten wirkt die unbequemste Maßnahme. Nehmen Sie Systeme vom Netz, die Sie nicht sofort patchen können, oder lassen Sie nur noch bekannte Adressen durch. CERT-EU, BSI und RUS-CERT nennen genau das als sichersten Weg bis zum Fix. Gina Peter Banyard hält es für das Vernünftigste, einen Server für einen Tag abzuschalten, wenn man es sich leisten kann. Sie räumt aber ein, dass man das von den meisten Betreibern kaum verlangen kann. In den Niederlanden haben einige große Seiten genau das getan.
Was gegen PHP2Shell nicht hilft
Einige Maßnahmen fühlen sich nach Schutz an, greifen bei PHP2Shell aber nicht. Der Grund ist fast immer derselbe: Sie laufen später als der verwundbare Code oder an der falschen Stelle.
Diese Schritte schützen nicht
- Ein Update von WordPress, Shopware oder TYPO3. Die Lücke steckt im Interpreter, nicht in der Anwendung.
- Sicherheits-Plugins und Middleware. Sie laufen erst, nachdem PHP den Request zerlegt hat.
- Der Wartungsmodus von Laravel. Auch er greift erst im Anwendungscode.
file_uploads = Off. Laut Vincent Schmalbach verarbeitet PHP den Multipart-Body trotzdem. Ein kleines post_max_size verkleinert dagegen laut PHP einen der Angriffswege.
ini_set() und .user.ini. Beide greifen erst, nachdem PHP den Request zerlegt hat.
error_reporting, display_errors oder ein @. PHP fasst den veralteten Zustand an, bevor es entscheidet, ob eine Meldung erscheint.
disable_functions. Wer Code auf Ebene des Interpreters ausführt, ist an die Funktionsliste von PHP nicht gebunden.
- Eine WAF, wenn der Server direkt erreichbar bleibt. Ein Request an die IP-Adresse des Servers läuft an Cloudflare und Co. vorbei.
Spuren eines Angriffs finden
Offizielle Angriffsindikatoren für PHP2Shell gibt es bislang nicht. Das BSI will die IOC-Listen, die im Netz kursieren, ausdrücklich noch nicht empfehlen. Verlässlicher ist die Suche nach Verhalten, das nach fast jeder erfolgreichen Codeausführung auftaucht. Huntress empfiehlt, PHP-Prozesse zu beobachten, die ungewöhnliche Kindprozesse starten.
Ein PHP-FPM-Worker, der eine Shell, python, perl, curl, wget oder nc startet, ist hochverdächtig. Dasselbe gilt für Befehle wie whoami, id oder uname -a unter dem Benutzer des Webservers. In den Logs lohnt der Blick auf auffällige Multipart-Requests und auf abgestürzte FPM-Worker ab dem Nachmittag des 20. Oktober. Der erste öffentliche Hinweis auf den Leak erschien gegen 15:20 UTC.
# Prozessbaum: Was startet php-fpm?
ps -eo pid,ppid,user,args --forest
# PHP-Dateien, die seit dem Leak neu sind
find /var/www -name "*.php" \
-newermt "2026-10-20 15:00" -ls
# .user.ini-Dateien im Web-Root
find /var/www -name ".user.ini" -ls
# Cronjobs des Webserver-Benutzers
sudo crontab -l -u www-data
Die Zeitangabe bei find gilt in der Zeitzone des Servers. 15:00 UTC entspricht 17:00 Uhr deutscher Sommerzeit. Passen Sie Pfad und Benutzernamen an Ihr System an.
Darüber hinaus gehören diese Stellen auf die Prüfliste: neue oder geänderte Dateien in Upload-Ordnern und Plugin-Verzeichnissen, Einträge mit auto_prepend_file, neue systemd-Units oder Supervisor-Programme, unbekannte SSH-Schlüssel und neue Administratoren im CMS. Ausgehende Verbindungen des Webserver-Benutzers zu unbekannten Zielen sind ebenfalls ein Warnsignal.
PHP selbst empfiehlt, die Fehlerprotokolle gezielt zu prüfen. Stellen Sie dafür in einer abgeschotteten Prüfung log_errors=On und error_reporting=E_ALL ein. Auffällig sind Warnungen und Deprecations, die vor dem eigentlichen Skript auftauchen, fatale Fehler, Maximum execution time exceeded und Meldungen beim Aufräumen nach dem Request. Das Advisory warnt aber ausdrücklich: Ein sauberes Log beweist nichts. Ältere Logs haben Deprecations oft gar nicht erfasst, und manche Fehler treten auf, bevor PHP überhaupt etwas schreibt.
Finden Sie einen klaren Hinweis auf einen PHP2Shell-Angriff, reicht Aufräumen nicht. Trennen Sie den Server vom Netz und sichern Sie die Logs. Bauen Sie das System neu auf und tauschen Sie jedes Geheimnis aus, das der PHP-Benutzer lesen konnte. Dazu zählen die .env-Datei, Datenbankpasswörter, API-Schlüssel und der App-Key Ihres Frameworks.
Wie weit Sie zurückschauen, hängt vom Risiko ab. Schmalbach empfiehlt den Zeitraum ab dem 20. Oktober gegen 15:00 UTC, kurz vor dem ersten öffentlichen Hinweis. Aikido rät, bis mindestens Juni 2026 zurückzugehen, nennt dafür aber keinen Grund. Für die meisten Server ist das Fenster ab dem Leak der Pflichtteil. Wer Zahlungsdaten oder Gesundheitsdaten verarbeitet, sollte weiter zurückgehen.
Die Quellenlage: wer was sagt
Zu PHP2Shell erscheinen gerade sehr viele Texte. Viele davon wiederholen dieselben drei Quellen, manche schmücken sie mit unbelegten Details aus. Diese Übersicht zeigt, auf wen sich dieser Artikel stützt und wie stark das jeweilige Wort wiegt.
| Quelle |
Beitrag |
Gewicht |
| PHP-Projekt (php.net) |
Sicherheitsadvisory vom 21.10. mit Ursache, Fix-Versionen und Notmaßnahmen, dazu zwei GitHub-Advisories mit allen Details |
maßgeblich |
| BSI |
Sicherheitshinweis vom 21.10., Stufe Orange, kein verlässlicher Workaround bekannt |
behördlich, vorsichtig |
| CERT-EU |
Advisory 2026-018, CVE-Nummern, Warnung vor allen Versionen ab PHP 5 |
behördlich, stützt sich auf Dritte |
| RUS-CERT, Universität Stuttgart |
eigener Test eines öffentlichen Exploits, Notbehelfe reichen nicht |
hoch, weil selbst geprüft |
| watchTowr |
frühe Bestätigung, dass die Lücken echt sind |
hoch, bei Angriffen überholt |
| Cloudflare |
erste Angriffe, WAF-Regeln für alle Kunden |
eigene Messdaten, keine Belege veröffentlicht |
| Huntress, Sansec, Tenable |
Erkennung über Prozessbäume, Zeitleiste, Warnung vor präpariertem Exploit-Code |
solide Fachfirmen |
| Vincent Schmalbach |
getestete Webserver-Regeln, Fallen beim Update |
Praxisquelle, kennzeichnet Unsicheres offen |
Die Liste zeigt ein Muster, das sich bei jedem großen Leak wiederholt. Die Behörden bleiben vorsichtig und verweisen auf PHP. Die Sicherheitsfirmen sind schneller, liegen aber auch öfter daneben. Für Entscheidungen auf Ihrem Server zählt am Ende das Advisory von PHP und der Hinweis Ihrer Distribution.
Häufige Fragen zu PHP2Shell
Diese Fragen tauchen in Foren und Hosting-Supports seit dem Leak immer wieder auf.
Mein WordPress ist aktuell. Bin ich trotzdem betroffen?
Ja. PHP2Shell steckt nicht in WordPress, sondern im PHP darunter. Ein aktuelles WordPress auf einem ungepatchten PHP ist genauso angreifbar wie ein altes. Entscheidend ist allein der PHP-Build auf dem Server.
Reicht es, session.upload_progress abzuschalten?
Nein. Laut Advisory blockiert der Schalter nur die nachgewiesenen Session-Wege von CVE-2026-109619. Gegen CVE-2026-109618 hilft er nicht. Vollständig schützt nur das Update. Ausgeschaltet lassen sollten Sie die Funktion trotzdem, wenn Sie sie nicht brauchen. Das rät PHP sogar für die Zeit nach dem Update.
Ich nutze noch PHP 7.4 oder 8.1. Was nun?
Vom PHP-Projekt gibt es kein neues Release. Für PHP 7.4, 8.0 und 8.1 hat das Sicherheitsteam aber minimale Quellcode-Patches veröffentlicht, gedacht für alle, die PHP selbst kompilieren. Prüfen Sie, ob Ihre Distribution einen zurückportierten Patch liefert. Gibt es keinen, nehmen Sie das System aus dem öffentlichen Netz und ziehen Sie die Migration auf PHP 8.4 oder 8.5 vor. Sie sind damit nicht allein: Laut einer Zählung von Mallory, die The Hacker News zitiert, melden rund 884.000 erreichbare Server PHP 8.1 oder älter.
Schützt mich Cloudflare vor PHP2Shell?
Teilweise. Cloudflare hat Regeln gegen bekannte Angriffsmuster ausgerollt und nennt sie selbst eine Übergangslösung. Sie helfen nur, wenn der Server ausschließlich über Cloudflare erreichbar ist. Antwortet er auch direkt auf seiner IP-Adresse, umgeht ein Angreifer die Regeln einfach.
Bin ich mit PHP-FPM sicherer als mit mod_php?
Etwas, aber nicht sicher. Den stärksten Exploit hat PHP gegen mod_php vorgeführt, weil der Angriff dort vor jedem Anwendungscode greift. FPM beendet einen Worker, dessen Request-Start scheitert, und entgeht damit dem direkten Weg. Über den Upload-Fortschritt hat PHP die Codeausführung aber auch gegen FPM nachgewiesen. Updaten müssen Sie in beiden Fällen.
Wie finde ich heraus, welche PHP-Version wirklich läuft?
Auf der Kommandozeile zeigt php -v die Version des CLI. Der Webserver nutzt oft eine andere. Für den Webserver liefert phpversion() den richtigen Wert. Lassen Sie dafür keine öffentliche phpinfo()-Seite liegen, sie verrät Angreifern gerade jetzt zu viel. Warum das so ist, steht im Tutorial zu phpinfo() absichern.
Mein Hoster hat noch nicht aktualisiert. Was kann ich tun?
Fragen Sie nach einem konkreten Termin und nennen Sie beide CVE-Nummern. Bis dahin können Sie über eine .htaccess oder die Panel-Einstellungen Uploads sperren, sofern Ihr Hoster das zulässt. Bei einem Online-Shop oder einer Seite mit Kundendaten ist ein vorübergehender Wartungsmodus auf Ebene des Webservers die sicherere Lösung.
Soll ich meinen Server mit einem der Exploits testen?
Nein. Tenable warnt, dass ungeprüfter Exploit-Code mitunter selbst Schadsoftware enthält. Andere Skripte funktionieren schlicht nicht und wiegen Sie in falscher Sicherheit. Spielen Sie das Update ein, statt Ihre Verwundbarkeit zu messen.
Fazit
Ich halte PHP2Shell für die ernsteste PHP-Lücke seit Jahren, und das nicht nur wegen des CVSS-Werts. Der Leak hat den üblichen Vorsprung der Verteidiger aufgefressen. Zwischen Bekanntwerden und Patch lag knapp ein Tag, und in dieser Zeit kursierten bereits Exploits.
Die gute Nachricht: Die Abhilfe ist einfach, wenn auch lästig. PHP aktualisieren, jeden Prozess neu starten, Container neu bauen. Den Upload-Fortschritt schalten Sie ab, wenn Sie ihn nicht brauchen. Wer das heute erledigt, hat das größte Risiko vom Tisch. Schwieriger haben es Betreiber alter Zweige. Für sie ist PHP2Shell der Moment, die aufgeschobene Migration nicht weiter aufzuschieben.
Unterschätzen Sie den letzten Schritt nicht. Ein Server, der vor dem Update angegriffen wurde, bleibt auch danach kompromittiert. Nehmen Sie sich nach dem Patch die Zeit für die Spurensuche. Und wenn ohnehin gerade alles auf dem Prüfstand steht: Jetzt die eigenen Upload-Formulare absichern.
(Autor:
schubertmedia), Eingetragen am 21.10.2026