Kurz gesagt: php_admin_value und php_admin_flag setzen PHP-Einstellungen im PHP-FPM-Pool oder in der Apache-Konfiguration so, dass Anwendungen sie weder per ini_set() noch per .htaccess ändern können. php.net verlangt genau das für die PHP2Shell-Übergangsmaßnahmen, etwa für memory_limit=-1. Nach dem Setzen muss der Dienst neu starten, und der Wert sollte im Webkontext geprüft werden.
Warum „gesetzt“ nicht „gesperrt“ heißt
In den Tagen nach dem 21. Oktober 2026 haben viele Administratoren die Übergangsmaßnahmen von php.net in ihre php.ini geschrieben. Ein Detail der Empfehlung ging dabei oft unter: memory_limit=-1 soll so gesetzt sein, dass Anwendungen es nicht überschreiben können. php.net nennt dafür ausdrücklich php_admin_value im FPM-Pool oder in der Apache-Konfiguration.
Der Grund ist einfach. Viele CMS, Shops und Frameworks setzen ihre eigenen Werte, etwa ein höheres Speicherlimit für Importe. Steht der Wert nur in der php.ini, überschreibt die Anwendung ihn beim nächsten Aufruf. Die Schutzmaßnahme existiert dann auf dem Papier, aber nicht im laufenden Prozess.
Das betrifft nicht nur PHP2Shell. Jede Härtung, von abgeschalteten Fehlerausgaben bis zu Upload-Grenzen, ist nur so stark wie ihre schwächste Ebene.
Wer PHP-Einstellungen überhaupt ändern darf
PHP kennt vier Änderungsmodi. Jede Einstellung hat einen davon, und er bestimmt, an welchen Stellen sie gesetzt werden kann. Die Bedeutungen stammen aus dem PHP-Handbuch.
| Modus | Wo der Wert gesetzt werden kann | Beispiele |
|---|---|---|
INI_USER |
im Skript per ini_set() und in .user.ini |
wenige Laufzeitwerte |
INI_PERDIR |
php.ini, .htaccess, httpd.conf, .user.ini |
post_max_size, session.upload_progress.enabled |
INI_SYSTEM |
nur php.ini oder httpd.conf |
file_uploads, disable_functions |
INI_ALL |
überall, auch per ini_set() |
memory_limit, display_errors, open_basedir |
Gefährlich sind vor allem INI_ALL-Werte: Sie lassen sich aus jedem Skript heraus ändern. INI_PERDIR-Werte lassen sich zwar nicht per ini_set() ändern, wohl aber über eine .htaccess bei mod_php oder eine .user.ini bei PHP-FPM. Wer Schreibrechte im Webroot hat, also auch eingeschleuster Code, kann solche Dateien anlegen.
php_admin_value im FPM-Pool und in Apache
Bei PHP-FPM stehen die Werte in der Pool-Datei. Das PHP-Handbuch hält fest: Mit php_admin_value und php_admin_flag gesetzte Werte lassen sich nicht per ini_set() überschreiben. Für Ein-Aus-Werte nehmen Sie php_admin_flag, für alle anderen php_admin_value.
; /etc/php/8.3/fpm/pool.d/seite1.conf (Auszug)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
memory_limit=-1 gehört laut php.net nur zusammen mit einer Speichergrenze über Container oder cgroup in die Konfiguration. Wie das mit systemd gelingt, steht im Beitrag Speichergrenzen mit systemd und cgroups setzen.
Bei Apache mit mod_php gehören die Direktiven in die Serverkonfiguration oder den VirtualHost. Laut PHP-Handbuch sind sie in .htaccess nicht erlaubt, und einmal gesetzt, kann weder .htaccess noch ini_set() sie ändern.
<VirtualHost *:443>
ServerName www.example.de
DocumentRoot /var/www/seite1/public
<IfModule php_module>
php_admin_value memory_limit -1
php_admin_value post_max_size 32M
php_admin_value upload_max_filesize 24M
php_admin_flag session.upload_progress.enabled off
php_admin_flag display_errors off
</IfModule>
</VirtualHost>
Zwei Feinheiten aus dem Handbuch: Um einen zuvor gesetzten Wert zu löschen, verwenden Sie none als Wert. Und PHP-Konstanten wie E_ALL haben in der Apache-Konfiguration keine Bedeutung; für error_reporting müssen Sie dort den Zahlenwert angeben.
Welche Werte Sie sperren sollten
Nicht jede Einstellung muss gesperrt sein. Sinnvoll ist das für alles, was Sicherheit betrifft oder als Übergangsmaßnahme dient:
- Die PHP2Shell-Übergangswerte von php.net:
memory_limit,post_max_size,upload_max_filesize,session.upload_progress.enabledund auf PHP 8.5fatal_error_backtraces. - Fehlerausgabe und Protokollierung:
display_errors,display_startup_errors,log_errors,error_log. - Dateizugriff und Isolation:
open_basedir,upload_tmp_dir,session.save_path. - Netzwerkzugriffe aus PHP:
allow_url_includeund, wenn die Anwendung es nicht braucht,allow_url_fopen. - Gesperrte Funktionen über
disable_functions, die im Pool laut Handbuch die php.ini-Liste ergänzen und nicht ersetzen. Details im Ratgeber disable_functions richtig einsetzen.
Bei session.upload_progress.enabled ist das Sperren besonders wichtig, weil der Wert sonst über eine .user.ini wieder eingeschaltet werden könnte. Mehr dazu unter session.upload_progress abschalten: richtig und dauerhaft.
Prüfen, ob die Sperre greift
Nach jeder Änderung starten Sie den Dienst neu und prüfen den Wert im Webkontext. Eine kurze, sofort wieder gelöschte Prüfdatei zeigt, ob der Pool den Wert hält, auch wenn die Anwendung ihn ändern will:
<?php
// Prüfdatei: kurz ablegen, einmal über die Domain aufrufen, sofort löschen
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
Erwartet wird -1 und „blockiert“. Lautet die Ausgabe „MÖGLICH“, ist der Wert nicht über php_admin_value gesetzt oder der Dienst noch nicht neu gestartet. Wiederholen Sie die Prüfung für jeden Pool und jede PHP-Version.
Halten Sie die gesperrten Werte zentral fest, etwa in einer Pool-Vorlage oder Ihrer Konfigurationsverwaltung. Hosting-Panels überschreiben handgeänderte Pool-Dateien teilweise beim nächsten Speichern; dort gehören die Werte in die vom Panel vorgesehenen Felder.
Wie PHP seine Konfigurationsebenen insgesamt ordnet, erklärt Die php.ini erklärt: Aufbau, Ebenen und Vorrang. Die vollständigen Übergangsmaßnahmen stehen unter Sofortmaßnahmen, wenn Sie noch nicht patchen können.
Fazit: Erst gesperrt ist wirklich gesetzt
Die Übergangsmaßnahmen von php.net zu PHP2Shell haben eine Unterscheidung ins Bewusstsein gerückt, die vorher oft übersehen wurde: Ein Wert in der php.ini ist für viele Einstellungen nur ein Vorschlag, ein Wert in php_admin_value eine Vorgabe. Für Komfortwerte wie die Zeitzone ist der Unterschied unerheblich. Für Sicherheitseinstellungen und Übergangsmaßnahmen entscheidet er darüber, ob die Maßnahme im laufenden Betrieb überhaupt greift.
Der Aufwand ist überschaubar: eine Handvoll Zeilen je Pool oder VirtualHost, ein Neustart, eine kurze Prüfung. Halten Sie die Liste der gesperrten Werte klein und begründet, damit Entwickler nachvollziehen können, warum ihre Anwendung einen Wert nicht ändern darf. Und pflegen Sie die Liste in Ihren Vorlagen, damit neue Websites sie automatisch erben.
Wie hilft PHP SOS konkret?
- Ebenen auslesen: Wir ermitteln für jede Website, welche Werte aus php.ini, Pool, Apache,
.htaccessoder.user.initatsächlich gelten. - Sperren setzen: Sicherheitsrelevante Werte und die PHP2Shell-Übergangsmaßnahmen tragen wir als
php_admin_valuebeziehungsweisephp_admin_flagein und starten die Dienste neu. - Anwendung testen: Wir prüfen, ob die Anwendung mit den gesperrten Werten fehlerfrei läuft, und werten das Fehlerlog aus.
- Vorlagen pflegen: Im Rahmen der Server-Härtung übernehmen wir die Werte in Pool-Vorlagen und Dokumentation.
Häufige Fragen
Was ist der Unterschied zwischen php_value und php_admin_value?
Beide setzen eine PHP-Einstellung. Werte aus php_value kann die Anwendung später wieder ändern, etwa per ini_set() oder .htaccess. Werte aus php_admin_value und php_admin_flag sind laut PHP-Handbuch für ini_set() gesperrt, bei Apache auch für .htaccess.
Kann ich php_admin_value in eine .htaccess-Datei schreiben?
Nein. Laut PHP-Handbuch ist php_admin_value in .htaccess-Dateien nicht erlaubt. Es gehört in die Apache-Serverkonfiguration oder den VirtualHost, bei PHP-FPM in die Pool-Datei.
Was passiert, wenn eine Anwendung einen gesperrten Wert ändern will?
Der Aufruf von ini_set() schlägt fehl und liefert false zurück, der gesperrte Wert bleibt bestehen. Gut programmierte Anwendungen kommen damit zurecht. Prüfen Sie nach der Umstellung trotzdem das Fehlerlog und die wichtigsten Funktionen.
Muss ich nach einer Änderung im Pool neu starten?
Ja. PHP-FPM liest die Pool-Dateien beim Start oder beim Neuladen des Dienstes. Bei Apache mit mod_php gilt dasselbe für die Serverkonfiguration. Ohne Neustart läuft der alte Wert weiter.
Lässt sich disable_functions im Pool erweitern?
Ja, mit einer Besonderheit: Laut PHP-Handbuch überschreibt disable_functions im FPM-Pool die Werte aus der php.ini nicht, sondern ergänzt sie. Der Pool kann also weitere Funktionen sperren, aber keine freigeben.