- SECURITY
- PHP NEWS
PHP2Shell: Kritische Lücken im PHP-Kern, so prüfst und schützt du deine Server
Zwei Lücken im PHP-Kern erlauben Codeausführung ohne Login. Welche Versionen betroffen sind, wie du in 5 Minuten prüfst und was bis zum Update hilft.

Kurz-Antwort: PHP2Shell ist der Name für zwei kritische Sicherheitslücken im PHP-Interpreter selbst (CVE-2026-109618 und CVE-2026-109619, je CVSS 9.2). Sie können ohne Login zu Codeausführung auf dem Webserver führen und betreffen jede PHP-Version vor 8.5.12, 8.4.27, 8.3.36 und 8.2.35. Die einzige vollständige Lösung ist das PHP-Update, ein Update von WordPress, Shopware oder Laravel reicht nicht.
Stand: 23.10.2026. Wir aktualisieren den Artikel, wenn sich die Lage ändert.
Was ist PHP2Shell?
PHP2Shell fasst zwei Speicherfehler im PHP-Kern zusammen. Das PHP-Security-Team hat sie am 21.10.2026 um 14:00 UTC zusammen mit neuen Versionen veröffentlicht (php.net, Security-Advisory vom 21.10.2026):
| CVE | Kurzname laut PHP | Was passiert |
|---|---|---|
| CVE-2026-109618 | RCE via OOM corruption | Läuft PHP genau dann in das Speicherlimit (memory_limit), wenn interne Request-Daten erst halb aufgebaut sind, behandelt das Aufräumen am Request-Ende diese Daten trotzdem als gültig. |
| CVE-2026-109619 | RCE via stale global state | Zustand eines Requests überlebt, obwohl sein Speicher schon freigegeben ist. Ein späterer Request im selben Worker greift darauf zu, bevor er zurückgesetzt wird (Use-after-free). |
Beide Lücken haben die Bewertung CVSS v4.0 9.2, also kritisch. Sie brauchen weder Login noch Klick eines Nutzers. Laut den Advisories kann ein Angreifer im schlimmsten Fall Code mit den Rechten des Web-Workers ausführen oder Speicherinhalte des Workers auslesen. Darin können Passwörter, Session-Tokens oder API-Schlüssel stehen.
Entdeckt haben die Fehler Forschende von Calif, Wiz Research und OpenAI, unabhängig voneinander (Wiz, php2shell.com; BleepingComputer, 21.10.2026). Der Name „PHP2Shell“ stammt aus dieser Forschung und steht für den Weg vom PHP-Prozess zur Shell auf dem Server.
Wie funktioniert die Lücke, grob erklärt?
Du musst keinen C-Code lesen, um das Risiko zu verstehen. Drei Punkte reichen:
- Der Fehler sitzt vor deinem Code. PHP verarbeitet den Request-Body, etwa ein
multipart/form-data-Formular mit Datei-Upload, bevor dein Framework überhaupt startet. Laut php.net ist das Risiko bei Apache mit mod_php am höchsten, weil der Angriff dort ausgelöst werden kann, bevor Anwendungscode läuft. - Fehlerfälle sind der Auslöser. Speicher voll, Zeitlimit überschritten, fataler Fehler oder Diagnose-Meldungen beim Herunterfahren: In diesen Ausnahmesituationen räumt PHP vor dem Fix nicht sauber auf.
- Worker werden wiederverwendet. PHP-FPM, mod_php, FrankenPHP und LiteSpeed bedienen viele Requests mit demselben Prozess. Was ein Request kaputt hinterlässt, trifft den nächsten. Für CVE-2026-109619 muss ein Angreifer deshalb mit mehreren Requests denselben Worker erreichen.
Betroffen sind laut php.net alle Installationen, die Web-Requests bedienen: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP und LiteSpeed. Der fehlerhafte Code reicht laut Sansec und Wiz bis PHP 5.4 aus dem Jahr 2012 zurück (Sansec).
Warum ist PHP2Shell gerade jetzt Thema?
Geplant war eine normale koordinierte Veröffentlichung. Am 20.10.2026 kündigte php.net ein kritisches Sicherheits-Release an (php.net, 20.10.2026), am selben Tag sickerten laut Sansec Details durch. Das Release kam deshalb schon am 21.10. um 14:00 UTC.
Cloudflare hat nach eigenen Angaben bereits ab 21.10. um 03:02 UTC Schutzregeln in seiner Web Application Firewall aktiviert und danach Angriffsverkehr gesehen, der die Regeln zu umgehen versuchte (Cloudflare-Blog). Sansec hat die Lage am 22.10. etwas entschärft: Öffentliche Proof-of-Concepts funktionieren gegen eine Standard-PHP-Installation nicht, eine Massenausnutzung sei weniger wahrscheinlich als am Release-Tag befürchtet. Patchen bleibt trotzdem Pflicht.
Wie groß die Baustelle ist, zeigen Zahlen von Qualys aus der eigenen Kundenbasis: Rund 71 % der gefundenen PHP-Installationen liefen auf Versionszweigen ohne regulären Support (Qualys, Stand 23.10.2026).
Welche PHP-Versionen sind betroffen, welche sind sicher?
| PHP-Zweig | Verwundbar | Sicher ab | Hinweis |
|---|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 | |
| 8.4 | < 8.4.27 | 8.4.27 | |
| 8.3 | < 8.3.36 | 8.3.36 | |
| 8.2 | < 8.2.35 | 8.2.35 | Support endet am 31.12.2026 |
| 8.1, 8.0, 7.4 | alle | kein offizielles Release | nur Quell-Patches auf GitHub oder Backports der Distribution |
| 8.6 (Vorabversion) | vor RC4 | 8.6.0 RC4 | nicht für Produktion |
Wichtig bei Linux-Distributionen: Debian, Ubuntu, Red Hat und andere spielen den Fix oft als Backport ein. Die Versionsnummer bleibt dann alt, zum Beispiel 8.1.x, das Paket ist aber trotzdem gepatcht. Dort zählt das Changelog des Pakets, nicht die Nummer.
Schritt für Schritt: So prüfst du deine Server
Schritt 1: Alle PHP-Installationen finden
Liste jeden Ort auf, an dem PHP Web-Requests bedient: Server, Container-Images, Shared Hosting, CI-Images, interne Tools und das alte Admin-Panel, das niemand mehr anfasst. Qualys weist zu Recht darauf hin, dass php -v oft eine andere Installation zeigt als die, die tatsächlich Requests ausliefert.
Schritt 2: Version prüfen, und zwar die richtige
php -v zeigt dir die Kommandozeilen-Version (CLI). Dein Webserver nutzt aber FPM oder mod_php, und das kann eine andere Binary mit einer anderen Konfiguration sein. Prüf beide:
php -v | head -1
php-fpm8.3 -v | head -1 # Name je nach System: php-fpm, php-fpm8.4, php85-fpm …
php-fpm8.3 -i | grep -E "^(memory_limit|session.upload_progress.enabled) "
Wir haben das am 23.10.2026 auf einem Mac mit Laravel Herd ausprobiert. Alle vier installierten Versionen (8.2.32, 8.3.32, 8.4.23, 8.5.8) waren zu dem Zeitpunkt noch nicht auf dem Fix-Stand. Auch Entwicklungsrechner gehören also auf die Liste, selbst wenn sie nicht öffentlich erreichbar sind.
Schritt 3: Mit einem kleinen Check-Skript prüfen
Das folgende Skript vergleicht die laufende Version mit dem Fix-Stand vom 21.10.2026 und zeigt die Einstellungen, die in den Advisories eine Rolle spielen. Es greift nichts an und ändert nichts.
<?php
// php2shell-check.php: prüft PHP-Version und Einstellungen zu CVE-2026-109618/-109619
// Stand der Fix-Versionen: php.net, 21.10.2026
$fixed = ['8.2' => '8.2.35', '8.3' => '8.3.36', '8.4' => '8.4.27', '8.5' => '8.5.12'];
$branch = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
echo 'PHP ' . PHP_VERSION . ' (' . PHP_SAPI . ")\n";
if (!isset($fixed[$branch])) {
echo "Status: Zweig $branch ohne offiziellen Fix, Distribution/Backport prüfen\n";
} elseif (version_compare(PHP_VERSION, $fixed[$branch], '<')) {
echo "Status: VERWUNDBAR, Update auf {$fixed[$branch]} oder neuer\n";
} else {
echo "Status: gepatcht (>= {$fixed[$branch]})\n";
}
$checks = [
'memory_limit' => ini_get('memory_limit'),
'post_max_size' => ini_get('post_max_size'),
'upload_max_filesize' => ini_get('upload_max_filesize'),
'max_input_nesting_level' => ini_get('max_input_nesting_level'),
'session.upload_progress.enabled' => ini_get('session.upload_progress.enabled') ? 'On' : 'Off',
'fatal_error_backtraces' => PHP_VERSION_ID >= 80500
? (ini_get('fatal_error_backtraces') ? 'On' : 'Off') : 'n/a (< 8.5)',
'display_errors' => ini_get('display_errors') ?: 'Off',
];
foreach ($checks as $key => $value) {
printf(" %-33s %s\n", $key, $value === false ? '(nicht gesetzt)' : $value);
}
Zwei Grenzen solltest du kennen: Auf der Kommandozeile zeigt das Skript die CLI-Konfiguration. Für die Web-Konfiguration rufst du es einmal über FPM oder mod_php auf, nur intern oder hinter Login, und löschst es danach wieder. Und bei Distributions-Paketen mit Backport meldet es „VERWUNDBAR“, obwohl der Fix drin sein kann. Dann entscheidet das Changelog:
# Debian/Ubuntu
zgrep -l "CVE-2026-109618" /usr/share/doc/php8.3*/changelog.Debian.gz
# RHEL, Alma, Rocky
rpm -q --changelog php-fpm | grep -m1 "CVE-2026-109618"Schritt 4: Updaten und alle Worker neu starten
Das Update ist der eigentliche Fix. Danach muss jeder laufende Prozess neu starten, sonst läuft der alte Code weiter: PHP-FPM, Apache, FrankenPHP, Queue-Worker, Laravel Octane, RoadRunner. Bei Docker baust du das Image mit dem neuen Basis-Tag neu und rollst die Container neu aus, ein docker restart reicht nicht. Danach Schritt 2 wiederholen.
composer update hilft hier nicht. Composer und composer audit kümmern sich um Pakete, nicht um die PHP-Binary. Dasselbe gilt für Updates von WordPress, Shopware, Magento oder Laravel: Die Lücke sitzt eine Ebene darunter.
Schritt 5: Übergangs-Härtung, wenn du nicht sofort updaten kannst
php.net und die GitHub-Advisories nennen Maßnahmen, die das Risiko senken. Alle Quellen sind sich einig: Keine davon macht ein System sicher. Sie überbrücken nur die Zeit bis zum Update.
Für CVE-2026-109619, in der FPM-Pool-Konfiguration (oder php.ini bei mod_php), danach alle Worker neu starten:
; /etc/php/8.x/fpm/pool.d/www.conf
php_admin_flag[session.upload_progress.enabled] = off
; nur PHP 8.5:
php_admin_flag[fatal_error_backtraces] = off
; Worker häufiger erneuern, wenn die Last es zulässt
pm.max_requests = 1ini_set() im Code und .user.ini reichen laut php.net ausdrücklich nicht, weil die Werte vor dem Parsen des Requests greifen müssen. Die Upload-Progress-Funktion empfiehlt das Advisory auch nach dem Update auszulassen, wenn du sie nicht brauchst. Die meisten modernen Anwendungen messen Upload-Fortschritt im Browser.

Der Screen zeigt das Prinzip: Die Werte stehen auf Off, die Version bleibt verwundbar.
Für CVE-2026-109618 empfiehlt php.net unter anderem ein kleines post_max_size (8M ohne Uploads, 32M mit Uploads), Größen- und Anzahl-Limits für Requests schon am Webserver oder Proxy und, wenn die Anwendung keine Formulare mit Datei-Upload braucht, das Blocken von multipart/form-data vor PHP. Für nginx sieht das etwa so aus:
# nur wenn deine Anwendung keine multipart-Formulare braucht
if ($http_content_type ~* "multipart/form-data") {
return 403;
}Das bricht Datei-Uploads, im Shop zum Beispiel Produktbilder im Admin. Teste vorher und nimm die Regel nach dem Update wieder raus.
Die Maßnahme memory_limit = -1 aus dem php.net-Advisory ist umstritten: Ohne Limit kann ein einzelner Request den ganzen Server-Speicher belegen. Wiz rät davon ab, wenn kein cgroup-Limit (etwa im Container) den einzelnen Worker begrenzt. RLIMIT_AS und RLIMIT_DATA sind laut Advisory kein Ersatz. Wenn du es setzt, dann nur vorübergehend und mit Monitoring.
Schritt 6: Logs prüfen
Es gibt keine eindeutige Signatur. Wiz nennt als Auffälligkeiten ungewöhnlich große oder kaputte PHPSESSID-Cookies, multipart-Requests mit anschließenden Speicherlimit-Fehlern oder gehäuften HTTP-500-Antworten sowie unerklärliche Abstürze und Neustarts von PHP-Workern. Ein schneller erster Blick ins PHP- oder FPM-Log:
grep -E "Allowed memory size .* in Unknown on line 0|exited on signal (11|6)" error.log
Die Zeilen im Screen sind Beispieldaten. „in Unknown on line 0“ heißt, dass der Fehler entstand, bevor ein Skript lief, also beim Verarbeiten des Requests selbst. Treffer beweisen keinen Angriff, und ein leeres Ergebnis beweist keine Sicherheit. Passt das Muster zeitlich zu großen POST-Requests im Access-Log, schau genauer hin. Bei Verdacht gilt das übliche Vorgehen: Zugangsdaten und Schlüssel tauschen, die auf dem Server lagen, und den Server auf fremde Dateien prüfen.
Einordnung für PHP-Entwickler
PHP2Shell ist ungewöhnlich, weil die Lücke nicht in einem Plugin oder Framework steckt, sondern im Interpreter. Sauberer Anwendungscode schützt dich nicht. Drei Lehren für den Alltag:
- Runtime-Updates gehören in den Prozess. Viele Teams halten Composer-Pakete aktuell, aber die PHP-Version im Docker-Image bleibt monatelang stehen. Ein fester Basis-Tag wie
php:8.4-fpmplus regelmäßiger Rebuild oder ein Bot wie Renovate für Image-Tags schließt diese Lücke. - EOL-Versionen werden teuer. Für PHP 8.1 und älter gibt es kein offizielles Release, nur Quell-Patches und Angebote von Distributionen und LTS-Anbietern. Und PHP 8.2 fällt am 31.12.2026 aus dem Support. Wer jetzt noch auf 8.1 sitzt, sollte das Upgrade auf 8.4 oder 8.5 ganz oben auf die Liste setzen.
- Fatale Fehler sind ein Sicherheitsthema. Das Advisory zu CVE-2026-109619 rät, von außen auslösbare fatale Fehler und Timeouts zu beheben, auch in Upload-, Import- und Cleanup-Code. Saubere Fehlerbehandlung und Limits für große Requests zahlen sich hier doppelt aus.
Für deinen Job heißt das: Wer erklären kann, wie PHP-FPM, Worker-Prozesse und php.ini-Ebenen zusammenspielen, ist in Teams mit eigener Infrastruktur gefragt. In vielen Stellenanzeigen steht „Betrieb“ oder „DevOps-Grundlagen“ nicht ohne Grund. Was Betriebswissen im Gehalt ausmacht, zeigt dir die Seite PHP Entwickler Gehalt.
ls --all alle aktuellen PHP Jobs
radar --new Job-Radar: neue PHP Jobs per E-Mail
FAQ
Quellen
- php.net: Security advisory: Critical remote code execution vulnerabilities, update now
- php.net: Upcoming Critical PHP Security Release
- php.net: Release PHP 8.5.12
- php.net: Release PHP 8.4.27
- php.net: Release PHP 8.3.36
- php.net: Release PHP 8.2.35
- GitHub php/php-src: GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
- GitHub php/php-src: GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
- Wiz Research: php2shell.com
- Sansec: PHP2Shell: PHP RCE
- Cloudflare: Protections against php2shell
- Qualys: Two Critical PHP Flaws PHP2Shell
- BleepingComputer: PHP ships emergency patches for critical PHP2Shell flaws
Job-Radar
Neue PHP-Jobs per E-Mail, sobald sie online sind.
Skill und Stadt wählen, eine E-Mail, Bestätigung per Klick. Abmelden jederzeit.