Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

php_admin_value: blokowanie ustawień przed nadpisaniem

Ustawienie bezpieczeństwa niewiele daje, jeśli aplikacja zmienia je jednym wierszem kodu. Za pomocą php_admin_value i php_admin_flag określają Państwo wartości dla PHP-FPM i Apache w sposób wiążący.

Stan 5 min czytaniaUtwardzanie i konfiguracja

Krótko: php_admin_value i php_admin_flag ustawiają opcje PHP w puli PHP-FPM lub w konfiguracji Apache tak, że aplikacje nie mogą ich zmienić ani przez ini_set(), ani przez .htaccess. Dokładnie tego wymaga php.net dla środków przejściowych PHP2Shell, na przykład dla memory_limit=-1. Po ustawieniu usługa musi zostać zrestartowana, a wartość sprawdzona w kontekście WWW.

Dlaczego „ustawione” nie znaczy „zablokowane”

W dniach po 21 października 2026 wielu administratorów wpisało środki przejściowe z php.net do swojego php.ini. Jeden szczegół zalecenia często przy tym umykał: memory_limit=-1 ma być ustawione tak, aby aplikacje nie mogły go nadpisać. php.net wymienia do tego wprost php_admin_value w puli FPM lub w konfiguracji Apache.

Powód jest prosty. Wiele systemów CMS, sklepów i frameworków ustawia własne wartości, na przykład wyższy limit pamięci dla importów. Jeśli wartość stoi tylko w php.ini, aplikacja nadpisze ją przy następnym wywołaniu. Środek ochronny istnieje wtedy na papierze, ale nie w działającym procesie.

Nie dotyczy to tylko PHP2Shell. Każde utwardzanie, od wyłączonego wyświetlania błędów po limity uploadu, jest tak silne jak jego najsłabszy poziom.

Kto w ogóle może zmieniać ustawienia PHP

PHP zna cztery tryby zmiany. Każde ustawienie ma jeden z nich i on określa, w jakich miejscach można je ustawić. Znaczenia pochodzą z podręcznika PHP.

Tryb Gdzie można ustawić wartość Przykłady
INI_USER w skrypcie przez ini_set() i w .user.ini nieliczne wartości czasu wykonania
INI_PERDIR php.ini, .htaccess, httpd.conf, .user.ini post_max_size, session.upload_progress.enabled
INI_SYSTEM tylko php.ini lub httpd.conf file_uploads, disable_functions
INI_ALL wszędzie, także przez ini_set() memory_limit, display_errors, open_basedir

Niebezpieczne są przede wszystkim wartości INI_ALL: można je zmienić z każdego skryptu. Wartości INI_PERDIR nie da się wprawdzie zmienić przez ini_set(), ale można to zrobić przez .htaccess przy mod_php lub .user.ini przy PHP-FPM. Kto ma prawa zapisu w katalogu głównym strony, a więc także wstrzyknięty kod, może takie pliki zakładać.

php_admin_value w puli FPM i w Apache

W PHP-FPM wartości stoją w pliku puli. Podręcznik PHP stwierdza: wartości ustawione przez php_admin_value i php_admin_flag nie dają się nadpisać przez ini_set(). Dla wartości włącz/wyłącz proszę użyć php_admin_flag, dla wszystkich pozostałych php_admin_value.

; /etc/php/8.3/fpm/pool.d/seite1.conf (fragment)
[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 należy według php.net do konfiguracji tylko razem z limitem pamięci przez kontener lub cgroup. Jak to się udaje z systemd, opisuje artykuł Ustawianie limitów pamięci za pomocą systemd i cgroups.

W Apache z mod_php dyrektywy należą do konfiguracji serwera lub VirtualHost. Według podręcznika PHP nie są dozwolone w .htaccess, a raz ustawione nie może ich zmienić ani .htaccess, ani ini_set().

<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>

Dwa niuanse z podręcznika: aby usunąć wcześniej ustawioną wartość, należy użyć none jako wartości. A stałe PHP takie jak E_ALL nie mają w konfiguracji Apache znaczenia; dla error_reporting trzeba tam podać wartość liczbową.

Które wartości warto blokować

Nie każde ustawienie musi być zablokowane. Ma to sens dla wszystkiego, co dotyczy bezpieczeństwa lub służy jako środek przejściowy:

  1. Wartości przejściowe PHP2Shell z php.net: memory_limit, post_max_size, upload_max_filesize, session.upload_progress.enabled oraz w PHP 8.5 fatal_error_backtraces.
  2. Wyświetlanie błędów i rejestrowanie: display_errors, display_startup_errors, log_errors, error_log.
  3. Dostęp do plików i izolacja: open_basedir, upload_tmp_dir, session.save_path.
  4. Dostęp sieciowy z PHP: allow_url_include oraz, jeśli aplikacja tego nie potrzebuje, allow_url_fopen.
  5. Zablokowane funkcje przez disable_functions, które w puli według podręcznika uzupełniają listę z php.ini, a nie ją zastępują. Szczegóły w poradniku Właściwe użycie disable_functions.

W przypadku session.upload_progress.enabled blokowanie jest szczególnie ważne, ponieważ wartość mogłaby inaczej zostać ponownie włączona przez .user.ini. Więcej w artykule Wyłączanie session.upload_progress: poprawnie i na stałe.

Sprawdzanie, czy blokada działa

Po każdej zmianie restartują Państwo usługę i sprawdzają wartość w kontekście WWW. Krótki, natychmiast usuwany plik testowy pokazuje, czy pula utrzymuje wartość, także gdy aplikacja chce ją zmienić:

<?php
// Plik testowy: umieścić krótko, wywołać raz przez domenę, od razu usunąć
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";

Oczekiwane są -1 i „blockiert”. Jeśli wynik brzmi „MÖGLICH”, wartość nie jest ustawiona przez php_admin_value albo usługa nie została jeszcze zrestartowana. Proszę powtórzyć sprawdzenie dla każdej puli i każdej wersji PHP.

Wskazówka

Proszę zapisywać zablokowane wartości centralnie, na przykład w szablonie puli lub w narzędziu do zarządzania konfiguracją. Panele hostingu częściowo nadpisują ręcznie zmienione pliki puli przy następnym zapisie; tam wartości należą do pól przewidzianych przez panel.

Jak PHP porządkuje swoje poziomy konfiguracji jako całość, wyjaśnia artykuł Plik php.ini wyjaśniony: budowa, poziomy i pierwszeństwo. Pełne środki przejściowe znajdują się na stronie Środki doraźne, gdy nie mogą Państwo jeszcze załatać.

Wniosek: dopiero zablokowane jest naprawdę ustawione

Środki przejściowe php.net dla PHP2Shell uświadomiły rozróżnienie, które wcześniej często pomijano: wartość w php.ini jest dla wielu ustawień tylko propozycją, a wartość w php_admin_value wytyczną. Dla wartości wygody, takich jak strefa czasowa, różnica jest nieistotna. Dla ustawień bezpieczeństwa i środków przejściowych rozstrzyga o tym, czy środek w ogóle działa w bieżącej pracy.

Nakład jest niewielki: garść wierszy na pulę lub VirtualHost, restart, krótkie sprawdzenie. Proszę utrzymywać listę zablokowanych wartości krótką i uzasadnioną, aby programiści mogli zrozumieć, dlaczego ich aplikacja nie może zmienić danej wartości. I proszę prowadzić listę w szablonach, aby nowe strony dziedziczyły ją automatycznie.

Jak konkretnie pomaga PHP SOS?

  • Odczyt poziomów: ustalamy dla każdej strony, jakie wartości z php.ini, puli, Apache, .htaccess lub .user.ini faktycznie obowiązują.
  • Ustawienie blokad: wartości istotne dla bezpieczeństwa i środki przejściowe PHP2Shell wpisujemy jako php_admin_value lub php_admin_flag i restartujemy usługi.
  • Test aplikacji: sprawdzamy, czy aplikacja działa bezbłędnie z zablokowanymi wartościami, i analizujemy log błędów.
  • Utrzymanie szablonów: w ramach utwardzania serwerów przenosimy wartości do szablonów pul i dokumentacji.

Częste pytania

Jaka jest różnica między php_value a php_admin_value?

Oba ustawiają opcję PHP. Wartości z php_value aplikacja może później zmienić, na przykład przez ini_set() lub .htaccess. Wartości z php_admin_value i php_admin_flag są według podręcznika PHP zablokowane dla ini_set(), a w Apache także dla .htaccess.

Czy mogę wpisać php_admin_value do pliku .htaccess?

Nie. Według podręcznika PHP php_admin_value nie jest dozwolone w plikach .htaccess. Należy do konfiguracji serwera Apache lub VirtualHost, a przy PHP-FPM do pliku puli.

Co się dzieje, gdy aplikacja chce zmienić zablokowaną wartość?

Wywołanie ini_set() kończy się niepowodzeniem i zwraca false, zablokowana wartość pozostaje. Dobrze zaprogramowane aplikacje sobie z tym radzą. Po przestawieniu proszę mimo to sprawdzić log błędów i najważniejsze funkcje.

Czy po zmianie w puli muszę zrestartować usługę?

Tak. PHP-FPM odczytuje pliki puli przy starcie lub przeładowaniu usługi. W Apache z mod_php to samo dotyczy konfiguracji serwera. Bez restartu działa dalej stara wartość.

Czy disable_functions można rozszerzyć w puli?

Tak, z jedną osobliwością: według podręcznika PHP disable_functions w puli FPM nie nadpisuje wartości z php.ini, lecz je uzupełnia. Pula może więc zablokować kolejne funkcje, ale żadnej nie może odblokować.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc