Stand aller Angaben: 21. Oktober 2026. Die Lage entwickelt sich schnell, Paketversionen und Herstellerhinweise können sich stündlich ändern. Prüfe vor jedem Schritt die verlinkten Primärquellen am Ende des Beitrags.
Am 21. Oktober 2026 hat das PHP-Team zwei kritische Sicherheitslücken im PHP-Interpreter selbst geschlossen. Sie laufen unter dem Namen php2shell und tragen die Kennungen CVE-2026-109618 und CVE-2026-109619, beide mit CVSS 4.0 von 9.2. Ein Angreifer kann damit ohne Anmeldung, nur über HTTP-Anfragen, eigenen Code auf deinem Webserver ausführen. Ursprünglich war die Veröffentlichung für den 22. Oktober geplant, nach einem vorzeitigen Bekanntwerden wurde sie um einen Tag vorgezogen.
Der entscheidende Punkt für dich: Die Lücke steckt nicht in WordPress, Nextcloud, Shopware oder Laravel, sondern eine Ebene darunter. Eine vollständig aktualisierte Anwendung schützt dich deshalb nicht. Selbst ein einfaches „Hallo Welt“-Skript kann als Einstieg genügen. Dieser Beitrag führt dich Schritt für Schritt durch Bestandsaufnahme, Update, Kontrolle und die Suche nach Spuren eines Einbruchs.
Die kurze Antwort
Aktualisiere PHP auf 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 beziehungsweise auf das gepatchte Paket deiner Distribution, und starte danach alle PHP-Prozesse neu. Ohne Neustart läuft der alte, verwundbare Code im Speicher weiter. Konfigurationsänderungen sind nur eine Notlösung für die Stunden, bis das Update da ist. Das PHP-Team, die Entdecker und alle Distributionen sagen übereinstimmend: Nur das Update schließt die Lücke vollständig.
Was technisch dahintersteckt
Beide Lücken betreffen den Umgang von PHP mit schweren Fehlern, vor allem mit dem Erreichen des Speicherlimits.
CVE-2026-109618 sitzt in der Speicherverwaltung. Bei einem Out-of-Memory-Fehler springt PHP bisher hart aus dem laufenden Kontext heraus. Passiert das in einem Moment, in dem interne Request-Daten erst halb aufgebaut sind, bleibt Speicher in einem ungültigen Zustand zurück. Beim Aufräumen am Ende der Anfrage behandelt PHP diese Daten als gültig. Einen solchen Speichermangel kann ein Angreifer gezielt herbeiführen, zum Beispiel mit präparierten Multipart-Uploads, sehr vielen Headern pro Formularteil oder tief verschachtelten Feldnamen. Das Ganze passiert beim Einlesen der Anfrage, also bevor deine Anwendung überhaupt eine Zeile Code ausführt.
CVE-2026-109619 betrifft Zustand, der nach einem schweren Fehler im Worker-Prozess hängen bleibt, obwohl der zugehörige Speicher schon freigegeben ist. Die erste Anfrage bringt den Prozess in diesen Zustand, eine spätere Anfrage an denselben Worker nutzt ihn aus. Dafür sind mindestens zwei Anfragen nötig.
Die Ausnutzung ist nicht trivial: Oft braucht es tausende, manchmal zehntausende Anfragen. Für ein Skript ist das aber kein Hindernis. Die Entdecker haben die Ausführung von Systembefehlen auf einem Laravel-Server in 38 Sekunden gezeigt, dazu Angriffe auf aktuelle Container von WordPress, Drupal und Joomla. Zusätzlich lässt sich Prozessspeicher auslesen, in dem Passwörter, Sitzungsschlüssel und API-Keys stehen können.
Wer ist betroffen?
| Betriebsart | Einschätzung laut PHP-Team |
|---|---|
| Apache mit mod_php | Am stärksten gefährdet, vollständige Codeausführung mit Standardeinstellungen nachgewiesen |
| PHP-FPM (nginx, Apache mit proxy_fcgi, Caddy) | Verwundbar, ein kompletter Exploit war zur Veröffentlichung noch nicht demonstriert |
| LiteSpeed LSAPI | Verwundbar, anwendungsspezifische Angriffe wahrscheinlich |
| FrankenPHP | Vermutlich verwundbar (nur per Quellcodeanalyse bewertet) |
| PHP auf Windows-Webservern | Verwundbar |
Betroffen sind praktisch alle PHP-Versionen der letzten Jahre. Wichtig ist, was oft übersehen wird: Viele Geräte nutzen PHP für ihre Weboberfläche, ohne dass man es ihnen ansieht. Dazu zählen Firewalls wie pfSense und OPNsense, NAS-Systeme, Router verschiedener Hersteller und manche Sicherheits-Appliances. Dazu später mehr.
Wird die Lücke schon ausgenutzt?
Zum Stand dieses Beitrags melden weder das PHP-Team noch die Entdecker bestätigte Angriffe in freier Wildbahn. Darauf solltest du dich aber nicht verlassen. Details sind vor dem Termin durchgesickert, Demonstrationen existieren, und Angriffe dieser Art lassen sich gut automatisieren. Erfahrungsgemäß beginnen breite Scans innerhalb weniger Tage nach so einer Veröffentlichung. Plane das Update für heute, nicht für das nächste Wartungsfenster.
Schritt 0: Bestandsaufnahme, wo überall PHP läuft
Bevor du einen einzigen Befehl ausführst, verschaffe dir einen Überblick. Mach eine Liste mit diesen Kategorien und hake sie nacheinander ab:
- Eigene Server und VMs mit Webanwendungen (WordPress, Nextcloud, Shop, Warenwirtschaft, Ticketsystem, interne Tools)
- Docker-Container, auch solche, bei denen PHP nur im Inneren läuft, etwa ein Mailserver mit Weboberfläche
- Raspberry Pi und Bastelrechner mit Dashboards, Nextcloud oder älterem Pi-hole
- Appliances: Firewall, NAS, Router, Telefonanlage, Kamera-Rekorder
- Webhosting-Pakete bei einem Hoster
Priorisiere nach Erreichbarkeit: Was direkt aus dem Internet erreichbar ist, kommt zuerst. Interne Systeme folgen unmittelbar danach, denn ein Angreifer, der bereits im Netz ist, kann sie genauso nutzen, um sich festzusetzen.
Schritt 1: Herausfinden, welches PHP wirklich läuft
Ein häufiger Fehler: php -v zeigt nur die Version der Kommandozeile. Der Webserver kann eine ganz andere Version nutzen, und auf vielen Servern sind mehrere PHP-Versionen parallel installiert. Prüfe deshalb die tatsächlich laufenden Prozesse:
# Laufende PHP-FPM-Master und Apache-Prozesse anzeigen
ps -eo pid,user,lstart,args | grep -E '[p]hp-fpm: master|[a]pache2 -k|[h]ttpd'
# Vorhandene FPM-Sockets zeigen, welche Versionen aktiv sind
ls /run/php/ 2>/dev/null
# Nutzt Apache mod_php?
apache2ctl -M 2>/dev/null | grep -i php
# Alle installierten PHP-Pakete mit Version (Debian, Ubuntu, Raspberry Pi OS)
dpkg -l | awk '/^ii/ && $2 ~ /^(php|libapache2-mod-php)/ {print $2, $3}'
Notiere dir für jedes System die PHP-Version (zum Beispiel 8.2 oder 8.4) und die Betriebsart (FPM oder mod_php). Taucht php_module in der Apache-Liste auf, hat dieses System die höchste Priorität.
Schritt 2: Paketquelle prüfen
Ob und wann ein Update für dich bereitsteht, hängt davon ab, woher deine PHP-Pakete kommen. Es gibt im Wesentlichen zwei Wege:
- Pakete der Distribution (Debian, Ubuntu, Raspberry Pi OS): Sie tragen eigene Versionsnummern. Ubuntu 24.04 liefert zum Beispiel weiterhin „8.3.6“ mit einem langen Anhang aus, der Fix steckt im Anhang. Die Versionsnummer von php.net hilft dir hier also nicht weiter.
- Fremdquellen wie das Repository von Ondřej Surý (packages.sury.org) für Debian oder sein PPA für Ubuntu: Hier entsprechen die Versionen den offiziellen Releases, also 8.2.35, 8.3.36 und so weiter.
Welche Quelle aktiv ist, verrät dir dieser Befehl. Ersetze die Versionsnummer durch deine aus Schritt 1:
apt-cache policy php8.2-fpm
# Für alle installierten PHP-Pakete auf einmal
for p in $(dpkg -l | awk '/^ii/ && $2 ~ /^(php[0-9.]+-(fpm|cgi|cli|common)|libapache2-mod-php)/ {print $2}'); do
echo "== $p"; apt-cache policy "$p" | sed -n '2,3p;/\*\*\*/,+1p'
done
Die Zeile mit den drei Sternchen zeigt die installierte Version und darunter die Quelle. Steht dort security.debian.org, security.ubuntu.com oder packages.sury.org, weißt du, wo du nach dem Fix suchen musst.
Diese Versionen enthalten den Fix
| System | Paket | Gepatchte Version (mindestens) |
|---|---|---|
| PHP offiziell, Sury, Docker-Images | 8.5 / 8.4 / 8.3 / 8.2 | 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 |
| Debian 13 „trixie“ | php8.4 | 8.4.27-1~deb13u1 (DSA-6574-1) |
| Debian 12 „bookworm“ (auch Raspberry Pi OS auf dieser Basis) | php8.2 | 8.2.35-1~deb12u1 (DLA-4848-1) |
| Ubuntu 26.04 LTS | php8.5 | 8.5.4-0ubuntu1.5 |
| Ubuntu 24.04 LTS | php8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | php8.1 | 8.1.2-1ubuntu2.28 |
| Ubuntu 20.04 LTS | php7.4 | 7.4.3-4ubuntu2.29+esm5, nur mit Ubuntu Pro |
| Debian testing und unstable | php8.4 | zum Stand des Beitrags noch offen |
Für PHP 7.4, 8.0 und 8.1 gibt es vom PHP-Team keine neuen Releases mehr, nur Patches für Paketbauer. Ubuntu und das Sury-Repository liefern dafür eigene Pakete. Ein altes PHP aus einer Distribution ohne Sicherheitsunterstützung, etwa PHP 7.4 auf Debian 11, bekommt dagegen keinen Fix. Das ist der Moment, in dem ein Umstieg nicht mehr warten kann.
Schritt 3: Vorher sichern
Ein PHP-Update ist normalerweise unspektakulär. Trotzdem: Mach vorher einen Snapshot der VM oder sichere zumindest die PHP-Konfiguration. Bei Proxmox dauert ein Snapshot Sekunden und erspart dir im Fehlerfall eine Nachtschicht. Wie eine belastbare Sicherung grundsätzlich aussieht, beschreibt unser Beitrag zur 3-2-1-Backup-Strategie.
sudo tar czf /root/php-config-$(date +%F).tar.gz /etc/php /etc/apache2 /etc/nginx 2>/dev/null
Schritt 4: Update einspielen
Auf Debian, Ubuntu und Raspberry Pi OS ist das Vorgehen identisch. Die Option --only-upgrade sorgt dafür, dass nur bereits installierte Pakete aktualisiert und keine neuen hinzugefügt werden:
sudo apt update
# Vorschau: Was würde aktualisiert?
apt list --upgradable 2>/dev/null | grep -E '^(php|libapache2-mod-php)'
# Nur die installierten PHP-Pakete aktualisieren
sudo apt install --only-upgrade $(dpkg -l | awk '/^ii/ && $2 ~ /^(php|libapache2-mod-php)/ {print $2}')
Taucht in der Vorschau kein PHP-Paket auf, ist für deine Quelle noch kein Fix verfügbar, oder du hast ihn schon. Das klärt Schritt 6. Ein vollständiges sudo apt full-upgrade ist natürlich ebenfalls richtig, wenn du das System ohnehin aktuell halten willst. Auf Red Hat, Alma oder Rocky Linux entspricht dem ein sudo dnf upgrade --refresh 'php*', sobald der Hersteller die Errata veröffentlicht hat.
Schritt 5: Alle PHP-Prozesse neu starten
Dieser Schritt ist nicht optional. Ein Paketupdate ersetzt die Dateien auf der Festplatte, aber die laufenden Worker haben den alten Code noch im Speicher. Starte deshalb alles neu, was PHP ausführt:
# Alle PHP-FPM-Dienste, egal welche Version
sudo systemctl restart 'php*-fpm.service'
# Bei mod_php: Apache vollständig neu starten, nicht nur neu laden
sudo systemctl restart apache2
# Falls Webserver und PHP anders heißen, zum Beispiel unter RHEL
sudo systemctl restart php-fpm httpd
Danach kontrollierst du, ob noch irgendein Prozess alte, inzwischen gelöschte PHP-Dateien im Speicher hält. Dieser Test ist zuverlässiger als jeder Blick auf Versionsnummern:
sudo grep -l 'php[^ ]* (deleted)' /proc/[0-9]*/maps 2>/dev/null
Liefert der Befehl keine Ausgabe, läuft nur noch neuer Code. Taucht ein Pfad auf, zeigt dir die Zahl darin die Prozess-ID, die du mit ps -p <PID> -o pid,args identifizieren und gezielt neu starten kannst. Wer das Paket needrestart installiert hat, bekommt dieselbe Information mit sudo needrestart -r l.
Ein ausgeführtes Update ohne Neustart der PHP-Dienste ist der häufigste Grund, warum ein System nach dem Patchtag trotzdem verwundbar bleibt. Prüfe den Neustart auf jedem einzelnen Server, auch wenn die Paketverwaltung „fertig“ meldet.
Schritt 6: Den Fix nachweisen
Verlasse dich nicht auf das Gefühl, alles aktualisiert zu haben. Zwei Kontrollen geben dir Gewissheit.
Erstens: Steht der Fix im Changelog? Debian und Ubuntu vermerken jede geschlossene CVE im Paket-Changelog:
apt changelog php8.2-fpm 2>/dev/null | grep -m4 -E 'CVE-2026-10961[89]'
# Ohne Internetzugriff, aus der lokalen Paketdokumentation
zcat /usr/share/doc/php8.2-common/changelog.Debian.gz | grep -m4 -E 'CVE-2026-10961[89]'
Beide CVE-Nummern müssen erscheinen. Fehlen sie, ist dein Paket noch nicht gepatcht.
Zweitens: Ist die installierte Version mindestens die gepatchte? Mit dpkg --compare-versions vergleichst du sauber, auch bei langen Distributionsnummern. Trage die Mindestversion aus der Tabelle oben ein:
v=$(dpkg-query -W -f='${Version}' php8.2-fpm)
dpkg --compare-versions "$v" ge 8.2.35-1~deb12u1 && echo "OK: $v" || echo "VERWUNDBAR: $v"
Zum Schluss prüfst du, dass die PHP-Dienste nach dem Update gestartet wurden, also die Startzeit jünger ist als dein Update:
systemctl show -p ActiveEnterTimestamp 'php*-fpm.service' apache2.service 2>/dev/null
Sonderfälle
Docker und Container
Ein Update auf dem Host bringt nichts, wenn PHP im Container läuft. Du brauchst ein neues Image und musst den Container neu erzeugen:
cd /pfad/zu/deinem/projekt
docker compose pull
docker compose up -d
# Bei selbst gebauten Images mit PHP-Basisimage
docker compose build --pull --no-cache
docker compose up -d
# Kontrolle im laufenden Container
docker compose exec <dienst> php -v
Achte auf fest angepinnte Tags. Steht in deinem Dockerfile FROM php:8.3.35-fpm, bekommst du mit keinem Pull der Welt den Fix, sondern musst den Tag auf 8.3.36 anheben. Bei fertigen Anwendungs-Images (Nextcloud, WordPress, Mailserver mit Weboberfläche) hängt es davon ab, dass der jeweilige Projektbetreiber ein neues Image baut. Prüfe nach dem Pull mit php -v im Container, ob die neue Version wirklich angekommen ist.
Raspberry Pi
Raspberry Pi OS basiert auf Debian, die Schritte 1 bis 6 gelten deshalb unverändert. Ob dein Pi überhaupt PHP nutzt, zeigt dpkg -l | grep php. Typische Kandidaten sind Nextcloud, selbst gebaute Dashboards und Pi-hole in Version 5 oder älter, das noch auf lighttpd mit PHP setzt. Pi-hole ab Version 6 bringt seinen eigenen Webserver mit und braucht kein PHP mehr, wie wir im Beitrag zu Pi-hole 6 beschrieben haben. Ein Grund mehr, umzusteigen.
Am gefährlichsten ist ein Pi, dessen Weboberfläche per Portfreigabe am Router aus dem Internet erreichbar ist. Nimm diese Freigabe bis zum Update zurück und greif stattdessen über ein VPN zu.
Firewalls, NAS und andere Appliances
Hier kannst du nicht selbst patchen, sondern musst auf den Hersteller warten. pfSense und OPNsense etwa bauen ihre Weboberfläche auf PHP auf, ebenso viele NAS-Systeme und Router. Was du sofort tun kannst:
- Prüfe, ob die Verwaltungsoberfläche aus dem Internet erreichbar ist. Wenn ja, schalte das ab. Eine Admin-Oberfläche gehört grundsätzlich nur ins Verwaltungsnetz oder hinter ein VPN, wie in unseren Firewall Best Practices beschrieben.
- Abonniere die Sicherheitshinweise deiner Hersteller und spiel deren Updates zeitnah ein, sobald sie erscheinen.
- Beschränke den Zugriff auf die Oberfläche intern auf wenige Admin-Adressen.
Webhosting
Bei einem klassischen Webhosting-Paket patcht der Hoster PHP für dich. Deine Aufgabe ist eine andere: Schau im Kundenmenü nach, welche PHP-Version für deine Seite eingestellt ist. Steht dort noch 7.4, 8.0 oder 8.1, stell auf mindestens 8.3 um, denn für diese alten Zweige ist nicht jeder Hoster in der Lage, einen Fix einzuspielen. PHP 8.2 erhält nur noch bis Ende 2026 Sicherheitsupdates, 8.3 bis Ende 2027. Teste die Umstellung zuerst an einer Kopie der Seite, wenn dein Hoster das anbietet.
Wir patchen deine PHP-Server
Keine Zeit oder kein Linux-Admin im Haus? Wir übernehmen Bestandsaufnahme, Update, Neustart und Nachweis für deine Server, Container und Appliances, prüfen auf Spuren eines Einbruchs und dokumentieren das Ergebnis. Kurzfristig, auch per Fernwartung.
Jetzt Unterstützung anfragenNotfallmaßnahmen, wenn das Update noch fehlt
Gibt es für dein System noch kein gepatchtes Paket, kannst du das Risiko mit Konfigurationsänderungen verringern. Sei dir dabei bewusst: Das PHP-Team nennt diese Maßnahmen ausdrücklich keinen vollständigen Schutz, und einige davon können deine Anwendung einschränken. Sie überbrücken Stunden, keine Wochen.
Lege für die Webserver-Variante von PHP eine eigene Datei an, damit du sie später mit einem Handgriff wieder entfernen kannst. Für PHP-FPM 8.2 sieht das so aus, bei mod_php liegt die Datei unter /etc/php/8.2/apache2/conf.d/:
sudo tee /etc/php/8.2/fpm/conf.d/99-php2shell-notfall.ini >/dev/null <<'EOF'
; Notfallmassnahme php2shell (CVE-2026-109618/109619)
; Nach dem Einspielen des Updates wieder entfernen!
session.upload_progress.enabled = 0
max_input_nesting_level = 8
max_input_vars = 1000
post_max_size = 8M
EOF
# Nur unter PHP 8.5 zusätzlich:
# fatal_error_backtraces = 0
sudo php-fpm8.2 -t && sudo systemctl restart php8.2-fpm
Was die Werte bewirken: session.upload_progress.enabled = 0 schaltet die Fortschrittsanzeige für Uploads ab, über die einer der Angriffswege läuft. Die übrigen Werte begrenzen Größe und Verschachtelung eingehender Anfragen, damit ein Angreifer den Speicher schwerer gezielt füllen kann. Beachte: post_max_size = 8M begrenzt auch legitime Uploads. Betreibst du eine Nextcloud oder ein System, über das große Dateien hochgeladen werden, musst du hier abwägen.
Ergänzend lohnt es sich, die Anfragegröße schon am Webserver zu begrenzen, bevor sie PHP erreicht. Bei nginx geschieht das mit client_max_body_size 8m;, bei Apache mit LimitRequestBody 8388608. Nutzt deine Anwendung gar keine Upload-Formulare, kannst du Multipart-Anfragen am Webserver oder an einer vorgeschalteten Web Application Firewall komplett blockieren. Mehrere große CDN- und Cloud-Anbieter haben für bekannte Angriffsmuster bereits Filterregeln ausgerollt, auch das ist aber nur eine Übergangslösung.
Die umstrittene Maßnahme: memory_limit = -1
Das PHP-Advisory nennt als wichtigste Konfigurationsmaßnahme, das Speicherlimit ganz aufzuheben. Das klingt widersinnig, folgt aber der Logik der Lücke: Ohne Limit gibt es keinen von PHP ausgelösten Out-of-Memory-Abbruch. Der Preis ist hoch. Ein einzelnes fehlerhaftes Skript kann dann den gesamten Arbeitsspeicher belegen, und auf einem Raspberry Pi oder einem kleinen Server ist das ein reales Risiko.
Wenn du diesen Weg gehst, dann richtig: Der Wert muss per php_admin_value[memory_limit] = -1 in jedem FPM-Pool erzwungen werden, damit keine Anwendung ihn per ini_set() oder .htaccess wieder setzen kann. Prüfe mit grep -rn memory_limit /etc/php/*/fpm/pool.d/ /etc/apache2/, ob irgendwo ein endliches Limit übrig bleibt. Begrenze außerdem auf keinen Fall den Speicher über ulimit -v oder ähnliche Prozesslimits, das löst laut Advisory genau den verwundbaren Pfad aus. Ein Speicherlimit des Containers oder des systemd-Dienstes ist möglich, beendet bei Überschreitung aber unter Umständen alle Worker gleichzeitig. Unsere Empfehlung: Diese Maßnahme nur auf Systemen mit reichlich Arbeitsspeicher, nur für wenige Stunden und nur, wenn das System aus dem Internet erreichbar ist und sich nicht vom Netz nehmen lässt.
Die sicherste Notfallmaßnahme bleibt ohnehin eine andere: Ist ein System nicht patchbar und nicht zwingend öffentlich nötig, nimm es vom Netz oder stell es hinter ein VPN, bis das Update da ist.
Schritt 7: Nach Spuren eines Einbruchs suchen
War ein System aus dem Internet erreichbar, solltest du nach dem Patchen prüfen, ob schon jemand drin war. Ein erfolgreicher Angriff läuft mit den Rechten des Webserver-Benutzers, unter Debian und Ubuntu also www-data. Genau dort setzt die Suche an. Passe das Datum an den Zeitraum an, in dem dein System ungepatcht erreichbar war:
# 1. Prozesse des Webserver-Benutzers, die keine PHP- oder Webserver-Prozesse sind
ps -u www-data -o pid,ppid,lstart,args --forest | grep -vE 'php-fpm|apache2|nginx'
# 2. Kürzlich geänderte oder neue PHP-Dateien im Webverzeichnis
sudo find /var/www -type f -name '*.php' -newermt '2026-10-14' \
-printf '%TY-%Tm-%Td %TH:%TM %u %p\n' | sort
# 3. Dateien des Webserver-Benutzers in temporären Verzeichnissen
sudo find /tmp /var/tmp /dev/shm -user www-data -type f -ls
# 4. Geplante Aufgaben, die sich ein Angreifer eingerichtet haben könnte
sudo crontab -l -u www-data
ls -la /etc/cron.d/ /var/spool/cron/crontabs/
# 5. Aktive Verbindungen nach außen, die von PHP-Prozessen ausgehen
sudo ss -tnp state established | grep -E 'php|"sh"|bash|perl|python'
Zu Punkt 5: Verbindungen von PHP zur eigenen Datenbank, zu Redis oder zum Mailserver sind normal. Auffällig sind Shell-Prozesse mit Netzwerkverbindungen und Verbindungen zu unbekannten Adressen im Internet.
Hinweise auf Angriffsversuche findest du außerdem in den Protokollen. Die Entdecker nennen als typische Muster: ungewöhnliche Multipart-Anfragen mit anschließenden Speicherfehlern, Häufungen von HTTP-500-Antworten und Worker, die auffällig oft neu starten. Bei Apache liegt das Zugriffsprotokoll unter /var/log/apache2/access.log.
# Speicherfehler in den PHP- und Webserver-Logs
sudo grep -c 'Allowed memory size' /var/log/php*-fpm.log /var/log/apache2/error.log /var/log/nginx/error.log 2>/dev/null
# Anzahl der HTTP-500-Antworten pro Tag (Standard-Logformat)
sudo awk '$9==500 {split($4,d,":"); print substr(d[1],2)}' /var/log/nginx/access.log | sort | uniq -c
# Abgestürzte oder beendete FPM-Worker in den letzten Tagen
sudo journalctl -u 'php*-fpm' --since '-7 days' | grep -cE 'exited on signal|exited with code'
Einzelne Speicherfehler oder 500er sind normal. Auffällig sind plötzliche Häufungen, die zeitlich zusammenfallen, besonders wenn sie von wenigen IP-Adressen kommen. Das Fehlen von Spuren ist kein Beweis für Sauberkeit, aber ein gutes Zeichen.
Wenn du etwas findest
- Nicht herumprobieren und nicht neu starten. Trenne das System vom Netz, lass es aber laufen, damit Speicherinhalte als Beweis erhalten bleiben.
- Protokolle sichern, und zwar auf ein anderes System, bevor sie rotiert oder vom Angreifer gelöscht werden.
- Nicht „reparieren“, sondern neu aufsetzen. Ein kompromittiertes System ist aus einer sauberen Sicherung von vor dem Einbruch wiederherzustellen, mit gepatchtem PHP.
- Alle Geheimnisse tauschen, die auf dem System lagen: Datenbankpasswörter, API-Schlüssel, Inhalte von
.env-Dateien, SMTP-Zugänge, Sitzungsschlüssel der Anwendung. - Meldepflicht prüfen. Sind personenbezogene Daten betroffen, verlangt Artikel 33 DSGVO eine Meldung an die Aufsichtsbehörde, unverzüglich und möglichst binnen 72 Stunden ab Kenntnis.
Ein Gedanke, der über den Einzelfall hinausgeht: Weil die Lücke auch das Auslesen von Prozessspeicher erlaubt, kann ein Angreifer Zugangsdaten mitgenommen haben, ohne Dateien zu verändern. Für Systeme, die mit wertvollen Schlüsseln arbeiten (Zahlungsanbieter, Cloud-Zugänge, E-Mail-Versand) und längere Zeit ungepatcht im Internet standen, ist ein vorsorglicher Tausch dieser Schlüssel deshalb eine vernünftige Entscheidung, auch ohne konkreten Fund.
Checkliste zum Abhaken
| Schritt | Kernbefehl oder Aktion | Dauer pro System | Erledigt |
|---|---|---|---|
| 0. Bestandsaufnahme | Liste aller Systeme mit PHP, nach Erreichbarkeit sortiert | ca. 30 Min. einmalig | ☐ |
| 1. Laufendes PHP ermitteln | ps, ls /run/php, apache2ctl -M | ca. 2 Min. | ☐ |
| 2. Paketquelle prüfen | apt-cache policy | ca. 2 Min. | ☐ |
| 3. Sichern | Snapshot oder Konfigurationsarchiv | ca. 2 Min. | ☐ |
| 4. Update | apt install --only-upgrade | ca. 5 Min. | ☐ |
| 5. Neustart | systemctl restart, danach Test auf gelöschte Dateien | ca. 2 Min. | ☐ |
| 6. Nachweis | Changelog und dpkg --compare-versions | ca. 3 Min. | ☐ |
| Container | docker compose pull bzw. build --pull, dann up -d | ca. 5 Min. | ☐ |
| Appliances | Verwaltung aus dem Internet nehmen, Herstellerupdate einplanen | ca. 15 Min. | ☐ |
| 7. Spurensuche | Prozesse, Dateien, Cronjobs, Verbindungen, Logs | ca. 15 Min. | ☐ |
Wer seine Systeme regelmäßig nach einem festen Schema prüft, ist bei der nächsten Lücke dieser Größenordnung schneller. Den größeren Rahmen dafür liefert unsere IT-Security-Checkliste. Und wer häufiger auf der Kommandozeile unterwegs ist, findet in unseren Linux-Befehlen für effizientes Arbeiten ein paar Werkzeuge, die bei der Spurensuche helfen.
Patchtage, die du nicht mitbekommst
Auch moderne Mailserver mit Weboberfläche enthalten PHP. Bei unserem Managed Mailcow gehören Updates, Überwachung und Sicherungen zum Leistungsumfang, damit eine Lücke wie php2shell nicht dein Feierabendprojekt wird.
Managed Mailcow ansehenHäufige Fragen
Reicht es, WordPress oder Nextcloud zu aktualisieren?
Nein. Die Lücken stecken im PHP-Interpreter, nicht in der Anwendung. Ein Angriff greift beim Einlesen der Anfrage, bevor der Code deiner Anwendung überhaupt läuft. Du musst PHP selbst aktualisieren und die PHP-Dienste neu starten.
Welche PHP-Versionen schließen die Lücken?
Offiziell 8.5.12, 8.4.27, 8.3.36 und 8.2.35. Bei Distributionspaketen zählt die Paketversion, zum Beispiel 8.2.35-1~deb12u1 auf Debian 12 oder 8.3.6-0ubuntu0.24.04.13 auf Ubuntu 24.04. Im Zweifel zeigt der Paket-Changelog, ob CVE-2026-109618 und CVE-2026-109619 enthalten sind.
Warum zeigt php -v noch die alte Version?
php -v zeigt die Kommandozeilenversion, nicht zwingend die des Webservers. Bei Distributionspaketen bleibt die Hauptversion außerdem gleich, nur der Anhang ändert sich. Entscheidend sind die Paketversion, der Changelog und ein Neustart der PHP-FPM-Dienste oder von Apache.
Ist mein Webhosting-Paket betroffen?
Der Hoster ist für das Patchen von PHP zuständig. Prüfe im Kundenmenü, welche PHP-Version deine Seite nutzt, und wechsle von 7.4, 8.0 oder 8.1 auf mindestens 8.3.
Reichen die Workarounds statt eines Updates?
Nein. Das PHP-Team bezeichnet die Konfigurationsänderungen ausdrücklich als unvollständig. Sie verringern das Risiko für die Zeit, bis das Update verfügbar ist, und einige davon können Uploads oder die Stabilität beeinträchtigen.
Sind Firewalls und NAS-Systeme betroffen?
Viele Geräte nutzen PHP für ihre Weboberfläche, darunter pfSense, OPNsense und zahlreiche NAS-Systeme und Router. Nimm deren Verwaltungsoberflächen aus dem Internet und spiel die Herstellerupdates ein, sobald sie erscheinen.
Fazit
php2shell ist eine der seltenen Lücken, die nicht eine einzelne Anwendung treffen, sondern das Fundament eines großen Teils des Webs. Die gute Nachricht: Das Update ist verfügbar, das Einspielen dauert pro Server wenige Minuten, und die Distributionen haben schnell reagiert. Die zwei Fallen sind banal und gerade deshalb gefährlich: Systeme, von denen man vergessen hat, dass sie PHP nutzen, und Dienste, die nach dem Update nicht neu gestartet wurden. Wer die Bestandsaufnahme ernst nimmt und jeden Fix nachweist, statt ihn anzunehmen, ist auf der sicheren Seite.
Quellen
- PHP Group: Security Advisory GHSA-w8hw-w9fx-j79w „RCE via OOM corruption“, 21. Oktober 2026
- php.net: Ankündigung der Releases 8.5.12, 8.4.27, 8.3.36 und 8.2.35, 21. Oktober 2026
- Debian Security Tracker: CVE-2026-109618 und CVE-2026-109619, DSA-6574-1, DLA-4848-1
- Ubuntu Security: CVE-2026-109618 und CVE-2026-109619, USN-8948-1 und USN-8948-2
- Wiz Research: php2shell, Analyse der Entdecker, 21. Oktober 2026
- heise online: „php2shell: Kritische Sicherheitslücken erlauben Codeeinschleusung in PHP“, 21. Oktober 2026