Das ist kein Fix
Laut PHP-Projekt gibt es für CVE-2026-109618 und CVE-2026-109619 keine vollständige Abhilfe. Sicher ist nur das Update auf 8.5.12, 8.4.27, 8.3.36 oder 8.2.35. Die Schritte unten verkleinern die Angriffsfläche, während Sie dieses Update vorbereiten. Ein Server mit sämtlichen Einstellungen von dieser Seite kann trotzdem verwundbar sein.
Gehen Sie die beiden CVEs einzeln an, denn jede hat eigene Einstellungen mit eigenen Nachteilen. Alle Werte unten gehören in die php.ini, die FPM-Pool-Datei oder die Webserver-Konfiguration. Setzen Sie sie nicht per ini_set(), .user.ini oder .htaccess: Dort können Anwendungscode und Nutzer sie ändern, und manche dieser Einstellungen werden von dort gar nicht gelesen.
CVE-2026-109619: veralteter globaler Zustand
Upload-Fortschritt abschalten
Die wichtigste Einstellung im Advisory zu dieser CVE ist session.upload_progress.enabled=0. Sie sperrt den frühen Session-Pfad, den der gezeigte Angriff nutzt. Die anderen Lebenszyklus-Pfade, die das Advisory beschreibt, deckt sie nicht ab.
In der php.ini:
session.upload_progress.enabled = 0
In einer FPM-Pool-Datei (zum Beispiel /etc/php/8.3/fpm/pool.d/www.conf), gesperrt, damit Skripte den Wert nicht ändern können:
php_admin_flag[session.upload_progress.enabled] = off
Bei Apache mit mod_php in der Server- oder VirtualHost-Konfiguration (nicht in der .htaccess, dort wird php_admin_flag abgelehnt):
php_admin_flag session.upload_progress.enabled off
Starten Sie danach jeden Worker neu: PHP-FPM, Apache mit mod_php, LiteSpeed. Die Neustart-Befehle auf der Seite Nach dem Patchen decken alle drei ab.
Lassen Sie die Einstellung auch nach dem Patch aus, wenn Sie keine Upload-Fortschrittsbalken nutzen. Das Advisory nennt die Funktion kaum genutzt und kaum getestet.
PHP 8.5: Backtraces bei fatalen Fehlern abschalten
Nur unter PHP 8.5 ergänzen Sie:
fatal_error_backtraces = 0
Laut Advisory entfällt damit der Auslöser, den der bestätigte Angriff verwendet. Anderen globalen Zustand pro Anfrage oder Zustand in Erweiterungen deckt das nicht ab. Starten Sie nach der Änderung jeden Worker neu.
Optional: jeden Worker nach einer Anfrage beenden
pm.max_requests = 1
Setzen Sie das als normale FPM-Pool-Direktive, ohne php_admin_value. Jeder Kindprozess bearbeitet eine Anfrage und beendet sich, sodass kein Zustand in die nächste Anfrage übergehen kann. Das Advisory schlägt das nur dort vor, wo Performance keine Rolle spielt: PHP-FPM forkt dann für jede Anfrage einen Prozess, und stark besuchte Sites werden deutlich langsamer. Außerdem senkt das Recycling laut Advisory nur die Erfolgschancen des Angreifers, die Bedingung selbst bleibt bestehen.
Mit Logs prüfen, und wissen, was nicht hilft
Schalten Sie für ein isoliertes Audit das Logging in der Startkonfiguration ein:
log_errors = On
error_log = /var/log/php/error.log
error_reporting = E_ALL
Suchen Sie in den Logs von PHP, Webserver und Proxy nach Warnungen oder Deprecation-Meldungen, die sich vor dem Skriptstart wiederholen, nach Diagnosen beim Aufräumen, nach fatalen Fehlern und nach Maximum execution time exceeded. Ein sauberes Log beweist keine Sicherheit.
Diagnosen zu unterdrücken bringt hier nichts. Laut Advisory schützt es nicht, error_reporting zu ändern, @ zu verwenden oder display_errors bzw. log_errors abzuschalten, weil der globale Zustand berührt wird, bevor PHP entscheidet, ob es überhaupt etwas meldet.
Zwei weitere Maßnahmen aus dem Advisory senken das Risiko: Entfernen Sie fatale Fehler und Timeouts aus Pfaden, die ein Angreifer erreicht (Upload, Import, Callbacks, Shutdown-Handler), und streichen Sie ungültige oder veraltete INI-Overrides pro Anfrage, die vor der Initialisierung Warnungen erzeugen.
CVE-2026-109618: Speicherbeschädigung bei Out-of-Memory
memory_limit=-1, und warum das falsch klingt
Der wichtigste Konfigurations-Workaround im Advisory ist das Gegenteil normaler Härtung:
memory_limit = -1
Gesperrt in einem FPM-Pool:
php_admin_value[memory_limit] = -1
Oder für mod_php:
php_admin_value memory_limit -1
Die Begründung: Der bestätigte Angriff ist darauf angewiesen, ein vorhersehbares Speicherlimit pro Anfrage zu erreichen. Ohne Limit fällt dieser Auslöser weg. Das Advisory nennt es trotzdem "not a complete mitigation", weil PHP denselben fehlerhaften Pfad erreichen kann, wenn das Betriebssystem eine Speicherzuweisung verweigert.
Das hat seinen Preis. Ein außer Kontrolle geratenes Skript, ein Bug oder eine große legitime Anfrage kann jetzt den gesamten Speicher des Hosts belegen. Gleichen Sie das auf anderen Ebenen aus: mit den Größenlimits am Frontend weiter unten und mit einer Speichergrenze pro Worker (siehe den Hinweis zu cgroups). Starten Sie alle Worker neu und prüfen Sie dann, dass kein Pool, kein Verzeichnis und keine Anwendungseinstellung wieder ein endliches Limit setzt. Nach dem Patch kehren Sie zu einem vernünftigen memory_limit zurück.
Anfragegröße verkleinern
post_max_size = 8M
upload_max_filesize = 2M
Nehmen Sie 8M, wenn die Site keine Uploads annimmt, und 32M, wenn sie es tut, und halten Sie upload_max_filesize kleiner als post_max_size. Die 2M oben sind ein Beispiel: Setzen Sie den Wert auf die größte Datei, die Ihre Nutzer tatsächlich hochladen. Senken Sie außerdem max_input_nesting_level (Standard 64) so weit, wie Ihre Formulare und APIs es vertragen, und sehen Sie sich max_input_vars und max_file_uploads an.
Anfragen am Frontend begrenzen
Die PHP-eigenen Limits reichen hier nicht. Laut Advisory soll das Frontend die dekodierte Anfragegröße durchsetzen und Anzahl der Felder, Multipart-Teile, Header und Verschachtelungstiefe begrenzen, auch für Anfragen ohne Content-Length-Header (Chunked Bodies). Wenn Ihre Anwendung keine Multipart-Formulare nutzt, blockieren Sie multipart/form-data, bevor es PHP erreicht.
nginx:
server {
client_max_body_size 8m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
}
nginx hat keine Einstellung für die Anzahl der Felder oder der Multipart-Teile. Dafür brauchen Sie eine WAF oder ein Application Gateway. Testen Sie auf Staging, dass übergroße Chunked Bodies ein 413 bekommen.
Apache:
LimitRequestBody 8388608
LimitRequestFields 50
LimitRequestFieldSize 8190
Apache zählt Chunked Bodies beim Einlesen mit und lehnt sie ab, sobald die Summe das Limit überschreitet. LimitRequestFields steht standardmäßig auf 100.
Container- und cgroup-Limits
Ein Speicherlimit auf Container oder cgroup kann memory_limit ersetzen, garantiert laut Advisory aber nicht, dass nie eine Speicherzuweisung fehlschlägt. Es hilft nur, wenn der Kill einen einzelnen Worker trifft. Wird der ganze Container oder die ganze cgroup beendet, geht der FPM-Master mit, und die Site bleibt down, bis etwas sie neu startet.
Kein RLIMIT_AS und kein RLIMIT_DATA
Das Advisory ist eindeutig: Verwenden Sie weder RLIMIT_AS noch RLIMIT_DATA, egal ob über ulimit -v, systemd LimitAS= oder LimitDATA= oder eine Container-Runtime. Wird eines dieser Limits erreicht, schlägt mmap() fehl, und genau dieser Fehlschlag löst den verwundbaren Pfad aus.
Die tatsächlich aktiven Einstellungen prüfen
Die Datei, die Sie bearbeitet haben, ist nicht unbedingt die, die PHP geladen hat. Overrides pro Pool, eingebundene Dateien und eine eigene php.ini pro SAPI sind verbreitet.
Prüfen Sie die Konfiguration, die PHP-FPM eingelesen hat (bei Debian-artigen Paketen heißt das Binary php-fpm8.3):
sudo php-fpm -tt 2>&1 | grep -E 'upload_progress|memory_limit|pm.max_requests|fatal_error'
Auf der Kommandozeile zeigt php -i die CLI-Konfiguration, die meist aus einer anderen Datei stammt. Fragen Sie stattdessen die Web-SAPI. Legen Sie diese Datei hinter eine IP-Allowlist oder Basic Auth, rufen Sie sie einmal auf und löschen Sie sie dann:
<?php
header('Content-Type: text/plain');
echo PHP_VERSION, ' ', PHP_SAPI, "\n";
foreach (['memory_limit','post_max_size','upload_max_filesize','max_input_nesting_level','session.upload_progress.enabled','fatal_error_backtraces'] as $k) {
echo $k, ' = ', var_export(ini_get($k), true), "\n";
}
phpinfo() zeigt dasselbe und noch viel mehr, darunter Pfade und Umgebungsvariablen. Halten Sie es von jeder öffentlichen URL fern und entfernen Sie es sofort wieder. fatal_error_backtraces gibt unter PHP vor 8.5 false aus, weil es die Einstellung dort nicht gibt.
Das eigentliche Update planen
Die Maßnahmen oben überbrücken ein paar Tage. Legen Sie für jeden Server fest, wohin er geht:
- Wählen Sie das Ziel. Wir empfehlen PHP 8.4 oder 8.3. Wechseln Sie nicht auf 8.2: Der Zweig erreicht am 31. Dezember 2026 sein Supportende.
- Für PHP 7.4, 8.0 und 8.1 hat das PHP-Projekt Backports als Quellcode und keine Releases veröffentlicht. Fragen Sie Ihre Distribution oder Ihren Anbieter für Langzeitsupport nach dem gepatchten Paket.
- Folgen Sie der allgemeinen Fix-Seite für Ihre Distribution oder Ihr Panel.
- Starten Sie nach dem Update neu, prüfen Sie mit Nach dem Patchen und entscheiden Sie dann, welche dieser Einstellungen bleiben.
session.upload_progress.enabled=0bleibt.memory_limit=-1undpm.max_requests=1kommen wieder raus.
Zuletzt geprüft am 22. Oktober 2026.