Öffnet in einem neuen Tab
Start › Blog › PHP-Sicherheitslücke CVE-2026-109618 und CVE-2026-109619: Was du vor und nach dem Patch tun musst

PHP-Sicherheitslücke CVE-2026-109618 und CVE-2026-109619: Was du vor und nach dem Patch tun musst

Veröffentlicht: 21. Oktober 2026
Zwei kritische PHP-Sicherheitslücken (CVSS 9,2) sind vor dem Patch durchgesickert. Betroffen ist praktisch jede PHP-Website – auch WordPress. Was du bis zum Update tun kannst, wie du richtig patchst und woran du einen Einbruch erkennst.

Stand: 21. Oktober 2026, Vormittag. Die gepatchten PHP-Versionen sind für heute 16:00 Uhr (MESZ) angekündigt. Ich aktualisiere diesen Beitrag, sobald das offizielle Advisory da ist.

Diese PHP-Sicherheitslücke betrifft nicht ein einzelnes Plugin, sondern PHP selbst. Also die Grundlage, auf der WordPress, WooCommerce, Laravel, Shopware und fast jede andere dynamische Website laufen. Das PHP-Team stuft beide Lücken als kritisch ein, mit 9,2 von 10 Punkten [php.net]. Und das Unangenehme: Die Details sind durchgesickert, bevor es einen Patch gibt.

Weiter unten findest du fertige Skripte für Ubuntu/Debian-Server, CloudPanel, Laravel Forge und Cloudflare. Für CloudPanel gibt es außerdem ein komplettes Skript zum Ein- und Ausschalten auf vielen Servern als GitHub Gist. Vielleicht spart das dem einen oder anderen heute ein paar Stunden.

Was ist passiert?

Am 20. Oktober hat das PHP-Sicherheitsteam ein Notfall-Release angekündigt: zwei kritische Schwachstellen, CVE-2026-109618 und CVE-2026-109619. Der Termin für die gepatchten Versionen ist Mittwoch, 21. Oktober 2026, 14:00 UTC – das ist 16:00 Uhr bei uns. Betroffene und gefixte Versionen nennt PHP erst mit dem Release. Das Team behält sich vor, früher zu veröffentlichen, falls Angriffe auftauchen [php.net].

Schon vorher sind laut Sicherheitsforschern Details öffentlich geworden. Mehrere Firmen sprechen von Remote Code Execution: Ein Angreifer könnte ohne Login eigenen Code auf dem Server ausführen. Die Lücke steckt nach bisherigen Berichten in der Verarbeitung von Datei-Uploads (multipart/form-data), insbesondere im Upload-Fortschritt der Sessions. PHP hat das nicht bestätigt [Vincent Schmalbach, Sansec].

Bestätigte Angriffe gab es bis heute früh keine. Sansec rechnet aber mit Massenangriffen sehr kurz nach dem Release, weil Angreifer dann den Patch vergleichen und den Fehler gezielt nachbauen können [Vincent Schmalbach].

Bist du von der PHP-Sicherheitslücke betroffen?

Sehr wahrscheinlich ja, wenn deine Website mit PHP läuft. CERT-EU schreibt, dass potenziell alle Versionen ab PHP 5 betroffen sein könnten, und rät, internetseitige Anwendungen notfalls vom Netz zu nehmen, bis ein Fix da ist [CERT-EU].

Wichtig für WordPress-Seiten: Es spielt keine Rolle, ob du ein Upload-Formular hast. PHP verarbeitet die Anfrage, bevor WordPress oder ein Sicherheits-Plugin überhaupt etwas davon mitbekommt. Wordfence, Maintenance-Modus oder Login-Schutz helfen hier nicht.

Offiziell unterstützt PHP derzeit die Zweige 8.2 bis 8.5. PHP 8.1 und älter bekommen sehr wahrscheinlich keinen Fix. Wenn deine Seite noch auf einer alten Version läuft, ist jetzt der Zeitpunkt für das Upgrade.

Was du jetzt tun solltest – je nach Hosting

Shared Hosting oder Managed Hosting

Hier patcht dein Hoster PHP, nicht du. Was du tun kannst:

  1. Schreib deinem Hoster heute noch und frag konkret: Wann wird der gepatchte PHP-Build eingespielt, und welche Version läuft dann für meine Domain?
  2. Prüf im Hosting-Panel, welche PHP-Version deine Seite nutzt. Steht dort 8.1 oder älter: auf 8.3 oder 8.4 umstellen und die Seite danach durchklicken.
  3. Als Übergangslösung kannst du den Upload-Fortschritt abschalten. Leg dafür im Hauptordner deiner Website (dort, wo die index.php liegt) eine Datei .user.ini an oder ergänze eine bestehende um diese Zeile. Das wirkt nach bis zu fünf Minuten.
session.upload_progress.enabled = Off

Das ist nur ein Pflaster. Laut Berichten gibt es möglicherweise einen zweiten Angriffsweg, den diese Einstellung nicht abdeckt.

Eigener Server (VPS, Root-Server, Cloud)

Hier liegt die Verantwortung bei dir. Bis zum Patch helfen zwei Maßnahmen. Beide sind keine offizielle Empfehlung von PHP – ein PHP-Core-Entwickler hat klargestellt, dass nur das Update wirklich schützt. Sie senken das Risiko aber für die paar Stunden bis dahin [Vincent Schmalbach].

  1. Upload-Fortschritt abschalten – in der php.ini und bei PHP-FPM zusätzlich fest in jedem Pool, damit eine .user.ini die Einstellung nicht wieder einschalten kann.
  2. Multipart-Anfragen am Webserver blocken – die stärkere Maßnahme. Jede Anfrage mit „multipart“ im Content-Type wird abgewiesen, bevor sie PHP erreicht, für alle HTTP-Methoden, nicht nur POST.

Die fertigen Befehle dafür findest du weiter unten.

Die Nebenwirkung musst du kennen: Solange der Block aktiv ist, funktionieren keine Datei-Uploads. Das betrifft die WordPress-Mediathek, Formulare mit Anhang und Upload-Felder in Laravel-Apps. Contact Form 7 schickt auch Formulare ohne Dateifeld als multipart – die fallen also ebenfalls aus. Normale Seiten, Logins und Formulare ohne multipart laufen weiter. Für ein paar Stunden ist das in den meisten Fällen verkraftbar.

Hinter Cloudflare oder einer anderen Firewall

Eine WAF davor kann zusätzlich blocken. Sie schützt aber nur Anfragen, die auch durch sie durchgehen. Wer deine Server-IP kennt, geht direkt drumherum. Der Block gehört deshalb immer auch auf den Server selbst.

Fertige Skripte zum Kopieren

Die Skripte setzen beide Übergangsmaßnahmen um. Sie sind für Ubuntu/Debian mit nginx und PHP-FPM gedacht. Lies sie kurz durch, bevor du sie ausführst, und teste danach.

Zur Map-Variante: Die Regel unten blockt neben multipart auch jede Anfrage mit PHPSESSID im Cookie oder in der URL (auch URL-codiert). Das schließt den Session-Weg mit ab, sperrt aber auch eingeloggte Nutzer von Anwendungen aus, die PHP-Sessions verwenden (z. B. phpMyAdmin, manche Shops und ältere Plugins). WordPress und Laravel nutzen eigene Cookies und merken davon meist nichts. Willst du nur Uploads blocken, nimm die Zeile mit dem langen Muster raus.

Upload-Fortschritt aus – für alle PHP-Versionen

Als root ausführen. Setzt die Einstellung in jeder php.ini und jedem FPM-Pool und lädt alle PHP-FPM-Dienste neu:

for ini in /etc/php/*/fpm/php.ini; do
  sed -i 's/^;?s*session.upload_progress.enabled.*/session.upload_progress.enabled = 0/' "$ini"
  grep -q '^session.upload_progress.enabled' "$ini" || echo 'session.upload_progress.enabled = 0' >> "$ini"
done

for pool in /etc/php/*/fpm/pool.d/*.conf; do
  grep -q 'session.upload_progress.enabled' "$pool" || 
    echo 'php_admin_flag[session.upload_progress.enabled] = off' >> "$pool"
done

for s in $(systemctl list-units --type=service --no-legend 'php*-fpm*' | awk '{print $1}'); do
  systemctl reload "$s"
done

grep -H 'session.upload_progress.enabled' /etc/php/*/fpm/php.ini

nginx: Map und Guard

Die Map gehört in den http { }-Kontext, am einfachsten als eigene Datei /etc/nginx/conf.d/php2shell.conf:

map "$http_cookie|$args|$content_type" $block_php2shell {
    default 0;
    "~*(?:p|%[57]0)(?:h|%[46]8)(?:p|%[57]0)(?:s|%[57]3)(?:e|%[46]5)(?:s|%[57]3)(?:s|%[57]3)(?:i|%[46]9)(?:d|%[46]4)" 1;
    "~*multipart/form-data" 1;
}

Und oben in jeden server { }-Block, der an PHP weitergibt – inklusive Default- bzw. Catch-all-Server:

if ($block_php2shell) { return 403; }

Danach:

nginx -t && systemctl reload nginx

Apache 2.4

In den VirtualHost oder in die .htaccess oberhalb der WordPress-Regeln. Nimm genau req('Content-Type') – %{CONTENT_TYPE} meint bei Apache den Typ der Antwort, damit läuft der Block ins Leere:

<If "req('Content-Type') =~ /multipart/i">
    Require all denied
</If>

CloudPanel

Am schnellsten mit dem fertigen Skript: Es schaltet den Upload-Fortschritt in allen PHP-Versionen aus, legt die Map an, setzt den Guard in alle Vhosts (inklusive Default-Host), sichert vorher /etc/nginx und rollt bei einem nginx-Fehler automatisch zurück. Mit off entfernst du alles wieder. Du findest es als php2shell-cloudpanel.sh auf GitHub Gist.

# ein Server
bash php2shell-cloudpanel.sh on

# viele Server auf einmal
for h in web01 web02 web03; do ssh root@$h 'bash -s' < php2shell-cloudpanel.sh on; done

# nur Uploads blocken, PHPSESSID nicht (z. B. Server mit CRM oder Shop)
ssh root@web01 'MULTIPART_ONLY=1 bash -s' < php2shell-cloudpanel.sh on

# nach dem PHP-Update
bash php2shell-cloudpanel.sh off

Wichtig: Das Skript schreibt direkt in die Vhost-Dateien. Solange der Block aktiv ist, keinen Vhost in der CloudPanel-Oberfläche speichern – sonst ist der Guard für diese Site weg.

Lieber von Hand? So geht es Schritt für Schritt:

  1. Per SSH als root das Skript „Upload-Fortschritt aus“ von oben ausführen. CloudPanel hat meist mehrere PHP-Versionen installiert, das Skript erwischt alle.
  2. Die Map als /etc/nginx/conf.d/php2shell.conf anlegen. Mit grep -n "conf.d" /etc/nginx/nginx.conf prüfen, ob der Ordner geladen wird. Falls nicht, die Map direkt in den http { }-Block der /etc/nginx/nginx.conf schreiben.
  3. In der CloudPanel-Oberfläche: Sites → Site → Vhost. Die Guard-Zeile oben in jeden server { }-Block setzen. PHP-Sites haben oft zwei Blöcke (z. B. 80/443 und 8080 für Varnish). Speichern. Über die Oberfläche ändern, nicht direkt in /etc/nginx/sites-enabled/ – sonst überschreibt CloudPanel das beim nächsten Speichern.
  4. Den Default-Host suchen und ebenfalls absichern: grep -rln "default_server" /etc/nginx/sites-enabled/ /etc/nginx/conf.d/
  5. nginx -t && systemctl reload nginx und von außen testen (siehe unten).

Laravel Forge als Recipe

In Forge unter Recipes → New Recipe anlegen, User root, dann auf die gewünschten Server ausführen. Das Recipe legt den Guard automatisch für jede Site ab und rollt bei einem nginx-Fehler alles zurück. Neuere Forge-Server benennen die Ordner unter forge-conf/ nach der Site-ID statt nach der Domain – die Schleife erwischt beides. Der Forge-Catch-all antwortet ohnehin mit 444.

Recipe „PHP2Shell Stopgap AN“

#!/bin/bash
set -e

# 1. Upload-Progress aus, alle PHP-Versionen
for ini in /etc/php/*/fpm/php.ini; do
  sed -i 's/^;?s*session.upload_progress.enabled.*/session.upload_progress.enabled = 0/' "$ini"
  grep -q '^session.upload_progress.enabled' "$ini" || echo 'session.upload_progress.enabled = 0' >> "$ini"
done

# auch fest in jedem FPM-Pool (gegen .user.ini)
for pool in /etc/php/*/fpm/pool.d/*.conf; do
  grep -q 'session.upload_progress.enabled' "$pool" || 
    echo 'php_admin_flag[session.upload_progress.enabled] = off' >> "$pool"
done

for s in $(systemctl list-units --type=service --no-legend 'php*-fpm*' | awk '{print $1}'); do
  systemctl reload "$s"
done

# 2. nginx Map (http-Kontext)
cat > /etc/nginx/conf.d/php2shell.conf <<'EOF'
map "$http_cookie|$args|$content_type" $block_php2shell {
    default 0;
    "~*(?:p|%[57]0)(?:h|%[46]8)(?:p|%[57]0)(?:s|%[57]3)(?:e|%[46]5)(?:s|%[57]3)(?:s|%[57]3)(?:i|%[46]9)(?:d|%[46]4)" 1;
    "~*multipart/form-data" 1;
}
EOF

# 3. Guard in jede Forge-Site (server-Kontext)
for dir in /etc/nginx/forge-conf/*/server; do
  echo 'if ($block_php2shell) { return 403; }' > "$dir/00-php2shell.conf"
done

# 4. Testen, bei Fehler alles zurückrollen
if nginx -t; then
  systemctl reload nginx
  echo "OK: Stopgap aktiv"
else
  rm -f /etc/nginx/conf.d/php2shell.conf /etc/nginx/forge-conf/*/server/00-php2shell.conf
  echo "nginx -t fehlgeschlagen, Änderungen entfernt"
  exit 1
fi

Recipe „PHP2Shell Stopgap AUS“ (nach dem Patch)

#!/bin/bash
rm -f /etc/nginx/conf.d/php2shell.conf /etc/nginx/forge-conf/*/server/00-php2shell.conf
nginx -t && systemctl reload nginx && echo "Block entfernt"

Kontrolle, ob der Guard überall liegt: ls /etc/nginx/forge-conf/*/server/

Cloudflare WAF-Regel

Security → WAF → Custom rules → Create rule → Edit expression, Aktion Block, deployen. Im Free-Plan sind fünf eigene Regeln möglich. Die Regel blockt PHPSESSID in Cookie und Query (auch klein geschrieben und URL-codiert) sowie alle multipart/form-data-Anfragen:

(lower(url_decode(http.cookie)) contains "phpsessid") or (lower(url_decode(http.request.uri.query)) contains "phpsessid") or (any(lower(http.request.headers["content-type"][*])[*] contains "multipart/form-data"))

Ob die Regel greift, siehst du unter Security → Events. Und noch einmal: Das ersetzt den Block am Server nicht.

Testen

Von außen, auch mit PUT. Erwartet wird ein 403 vom Webserver. Mit --resolve deine-domain.at:443:DEINE-SERVER-IP prüfst du zusätzlich den direkten Weg am CDN vorbei:

curl -sS -o /dev/null -w '%{http_code}n' -F test=1 https://deine-domain.at/
curl -sS -o /dev/null -w '%{http_code}n' -X PUT -F test=1 https://deine-domain.at/index.php

Was nicht schützt

  • WordPress-Sicherheitsplugins, auch die Firewall von Wordfence im erweiterten Modus – sie laufen erst, wenn PHP die Anfrage schon zerlegt hat.
  • file_uploads = Off – PHP liest den multipart-Body trotzdem.
  • Kleine Upload-Limits oder disable_functions.
  • Maintenance-Modus in WordPress oder Laravel.

Nach dem Patch: richtig aktualisieren

  1. Logs sichern, bevor du patchst. Webserver- und PHP-Logs seit 20. Oktober kopieren. Die brauchst du für die Prüfung auf einen Einbruch.
  2. Prüfen, ob die Paketquelle den Fix schon hat. Unter Debian/Ubuntu: sudo apt update, dann apt-cache policy php8.3-fpm. Distributionen portieren Fixes zurück, die Versionsnummer sieht deshalb oft „alt“ aus. Entscheidend ist der Changelog des Pakets.
  3. Alle installierten PHP-Versionen aktualisieren, nicht nur die, auf die der php-Befehl zeigt. Mit apt-mark showhold prüfen, ob ein Paket gesperrt ist – dann passiert beim Update stillschweigend nichts.
  4. PHP-FPM und alle Dauerläufer neu starten: Queue-Worker, Horizon, Scheduler, Octane. Die laufen sonst mit dem alten Binary weiter. Übrig gebliebene Prozesse findest du mit ls -l /proc/*/exe 2>/dev/null | grep -i 'php.*deleted'.
  5. Docker-Images neu bauen und neu deployen. Ein laufender Container bekommt den Fix nicht automatisch.
  6. Blocks wieder entfernen (nginx, CloudPanel-Skript mit off, Forge-Recipe „AUS“, Cloudflare-Regel deaktivieren) und Uploads sowie Formulare testen. Den Upload-Fortschritt kannst du ausgeschaltet lassen.

Prüfen, ob jemand schon drin war

Schau zurück bis zum Nachmittag des 20. Oktober – kurz davor wurde das Leak öffentlich:

  • Logs nach auffälligen multipart-Anfragen und abgestürzten PHP-FPM-Workern durchsuchen.
  • Neue oder geänderte Dateien im Webroot, im Upload-Ordner, in Plugins und mu-plugins suchen, z. B. mit find /var/www -type f -newermt '2026-10-20 15:00 UTC'.
  • .user.ini-Dateien und auto_prepend_file auf Änderungen prüfen.
  • Cronjobs, systemd-Units und SSH-Keys auf neue Einträge kontrollieren.
  • In WordPress und anderen Anwendungen nach unbekannten Admin-Konten schauen.

Findest du etwas: Server isolieren, Logs aufheben, neu aufsetzen und alle Zugangsdaten tauschen, die der PHP-Benutzer lesen konnte – wp-config.php, .env, Datenbank-Passwörter, API-Keys.

Meldepflicht in Deutschland, Österreich und der Schweiz

Wurde ein Server tatsächlich übernommen, waren meist auch personenbezogene Daten im Zugriff: Kundenkonten, Bestellungen, Formulareingaben. In Deutschland und Österreich greift dann Art. 33 DSGVO – Meldung an die zuständige Datenschutzbehörde innerhalb von 72 Stunden ab Kenntnis. In der Schweiz verlangt Art. 24 revDSG eine Meldung an den EDÖB „so rasch als möglich“. Deshalb ist die saubere Prüfung nach dem Patch kein Extra, sondern Pflicht.

Häufige Fragen

Ist meine WordPress-Seite von der PHP-Sicherheitslücke betroffen?

Wenn sie auf PHP läuft – und das tut jede WordPress-Seite –, solltest du davon ausgehen. Die Lücke sitzt in PHP selbst, nicht in WordPress. Ein WordPress-Update schließt sie nicht.

Reicht es, wenn mein Hoster patcht?

Bei Shared Hosting ja – aber frag nach, ob und wann der gepatchte Build für deine Domain aktiv ist. Bei mehreren PHP-Versionen im Panel heißt „Version umstellen“ nicht automatisch „gepatcht“.

Was ist mit PHP 7.4 oder 8.1?

Diese Versionen sind End of Life. Ein offizieller Fix ist nicht zu erwarten. Die Übergangsmaßnahmen müssen bleiben, bis die Seite auf eine unterstützte Version umgezogen ist.

Schützt mich ein Sicherheits-Plugin wie Wordfence?

Nein. Diese Plugins laufen erst, nachdem PHP die Anfrage verarbeitet hat. Für diese Lücke kommen sie zu spät.

Kann ich die Skripte einfach so ausführen?

Sie sind für gängige Ubuntu/Debian-Setups gedacht. Jeder Server ist anders – lies sie vorher durch, führe nginx -t aus und teste danach mit curl. Das CloudPanel-Skript und das Forge-Recipe rollen bei einem nginx-Fehler selbst zurück.

Du weißt nicht, auf welcher PHP-Version deine Seite läuft, oder willst das heute nicht selbst am Server machen? Schreib mir, ich schaue es mir mit dir an. Wer solche Updates nicht jedes Mal selbst verfolgen will, findet bei meiner WordPress-Wartung genau das: Updates, Kontrolle und jemand, der bei so einem Tag schon dran ist.

Quellen

KI-Transparenz: Die Beitragsbilder in diesem Blog werden mit KI generiert, die Texte entstehen in der Regel mit KI-Unterstützung. Jeder Beitrag wird von mir redaktionell geprüft und inhaltlich verantwortet. So arbeite ich mit KI

Inhalt

Keine Lust auf Selbermachen?

Ich richte deine WordPress-Seite sicher ein — inkl. DSGVO-Check.
Erstgespräch buchen

Passende Beiträge

Geschrieben von Christoph Purin

Webentwickler und zertifizierter Web Accessibility Expert aus Vorarlberg. WordPress seit 2005. Jeder Beitrag basiert auf echten Projekten — alles selbst getestet.
Mehr über mich →So arbeite ich mit KI →

Sprich mit mir über dein Projekt.

30 Minuten, kostenlos, unverbindlich. Du bekommst eine klare Einschätzung. Auch wenn sie lautet: „Dafür brauchst du mich nicht.“
Erstgespräch buchen
Antwort innerhalb von 48 Stunden · hallo@purin.at · +43 660 744 13 58