Текуща ситуация: PHP2Shell. Две критични уязвимости в PHP (CVSS 9,2) позволяват злонамерен код без вход. Корекции от 21.10.2026 г.Какво да направите сега →

Правилно използване на PHP disable_functions

С disable_functions заключвате рисковите функции на PHP. Как да определите списъка според приложението си, без да спрете уебсайта.

Актуалност 5 мин. четенеНаръчници

Накратко: С PHP disable_functions заключвате функциите, чрез които PHP изпълнява системни команди, например exec, shell_exec или proc_open. Това затруднява следващата стъпка на атакуващите след проникване. Настройката действа само от php.ini или FPM пула, трябва да отговаря на приложението и не замества актуализацията.

Защо disable_functions е разумна именно сега

При PHP2Shell става дума за отдалечено изпълнение на злонамерен код без вход в системата. Двете уязвимости CVE-2026-109618 и CVE-2026-109619 са в самия интерпретатор на PHP, поправени в PHP 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Актуализацията е единственият начин да се затворят.

Заздравяването действа едно ниво по-късно. Който веднъж може да изпълнява код на сървър, обикновено иска да продължи: да стартира системни команди, да зареди допълнителни инструменти, да създаде трайна задна вратичка. Много от тези стъпки минават през малко PHP функции. Ако те са заключени, пътят става по-труден и по-забележим.

Затова disable_functions не е заместител на пачовете, а градивен елемент за случая, когато въпреки всички предпазни мерки нещо се промъкне. Това важи за бъдещи уязвимости така, както за PHP2Shell.

Какво постига PHP disable_functions и какво не

Настройката премахва посочените функции от средата за изпълнение. Ако скрипт извика заключена функция, PHP прекъсва с грешка. Заключването важи за всеки код, който работи в този PHP процес, т.е. и за внедрен код.

Границите трябва да познавате:

  • Настройката не е изолирана защитна зона. Разширения на PHP, грешки в интерпретатора или програми извън PHP могат да я заобиколят.
  • Тя не пречи на атакуващия да чете или записва файлове, до които потребителят на PHP има достъп. За това отговарят правата за файлове и изолацията.
  • Тя действа само от php.ini или като php_admin_value. С ini_set(), .user.ini или .htaccess не може да се зададе.

Най-много disable_functions дава заедно с чиста php.ini, отделни потребители за всеки уебсайт и ограничителни права за файлове. Основите са описани в наръчника Сигурно конфигуриране на php.ini.

Кои функции да заключите

За типични уебсайтове без нужда от системни команди се е доказал следният списък. Той включва функции за стартиране на процеси и за управление на работещи процеси.

Група Функции Типично законно приложение
Изпълнение на команди exec, shell_exec, system, passthru Обработка на изображения, архивиране със скрипт
Отваряне на процеси proc_open, popen Composer, PDF инструменти, изпращане на поща
Управление на процеси proc_nice, proc_terminate, proc_get_status Опашки, фонови задачи
Администриране на процеси pcntl_exec, pcntl_fork най-често само в командния ред
Сигнали и права posix_kill, posix_setuid рядко в уеб режим

Като конфигурация това изглежда така:

; php.ini на уеб режима на работа, напр. /etc/php/8.3/fpm/php.ini
disable_functions = exec,shell_exec,system,passthru,proc_open,popen,proc_nice,proc_terminate,proc_get_status,pcntl_exec,pcntl_fork,posix_kill,posix_setuid

Ако списъкът не важи за всички уебсайтове на сървъра, задайте го за всеки FPM пул. След презареждането проверете кой списък действително важи в този пул:

; /etc/php/8.3/fpm/pool.d/meine-seite.conf (откъс)
php_admin_value[disable_functions] = exec,shell_exec,system,passthru,proc_open,popen

Проверка на приложението предварително: така избягвате откази

Който зададе списъка непроверено, рискува уголемяването на изображения, PDF фактурите или изпращането на поща изведнъж да спрат да работят. Затова предварително потърсете засегнатите функции в кода:

# Къде и колко често се използват функциите в кода?
grep -rnoE "\b(exec|shell_exec|system|passthru|proc_open|popen|pcntl_exec)\s*\(" /var/www/meine-seite --include="*.php" \
  | cut -d: -f1 | sort | uniq -c | sort -rn | head -30

Намерените резултати не означават автоматично, че функцията се използва в експлоатация. Много библиотеки първо проверяват дали функцията е налична и в противен случай заобикалят. Решаващ е тест в staging среда с всички важни процеси: поръчка, фактура, изпращане на формуляр, качване на изображение, планирани задачи.

Ако приложението задължително изисква някоя от тези функции, проверете системните изисквания на производителя на неговата официална страница. Често задачата може да се премести в отделен пул или в скрипт за командния ред, който не е достъпен през уеб.

Активиране на настройката и проверка на ефекта

След промяната PHP трябва да прочете конфигурацията наново. След това проверете стойността в режима на работа на Вашия уебсайт, а не в командния ред:

sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep "^disable_functions"
# Проверка на лога на грешките за извиквания на заключени функции
sudo grep -i "has been disabled" /var/log/php/*.log | tail -20

Съобщенията в лога на грешките са ценни и по-късно. Ако там изведнъж се появят извиквания на заключени функции, макар Вашето приложение да не ги използва, това може да сочи към внедрен код. Как да продължите тогава, описва наръчникът Разпознаване и премахване на уеб шелове.

Типични грешки при използването на disable_functions

На практика заздравяването рядко се проваля заради технологията, а заради дреболии. Тези грешки са особено разпространени:

  • Променен грешен файл: Списъкът е само в php.ini на командния ред, уебсайтът работи през PHP-FPM и остава незащитен.
  • Липсващ рестарт: Файлът е правилен, но работещите процеси още използват старата конфигурация.
  • Прекалено широко заключване: Функции като ini_set или mail се заключват заедно с останалите и важни процеси прекъсват незабелязано. Грешките често се забелязват едва след дни, например при липсващи потвърждения на поръчки.
  • Веднъж зададено, никога непроверено: След преместване, смяна на версията на PHP или нова инсталация през хостинг панел списъкът е изчезнал.
  • Фалшиво чувство за сигурност: Заключването се възприема като заместител на актуализациите. То обаче не затваря уязвимост в интерпретатора.

Затова включете проверката на активната стойност в рутината си след всяка актуализация на PHP. Един кратък поглед е достатъчен, струва малко време и пречи заздравяването да бъде загубено тихо.

Съвет

При няколко уебсайта на един сървър: създайте за всеки уебсайт отделен пул със собствен списък. Допълнително open_basedir ограничава директориите, до които PHP има достъп.

Как конкретно помага PHP SOS?

  • Проверяваме кода и процесите на Вашето приложение за използване на критични функции.
  • Определяме за всеки уебсайт подходящ списък със заключени функции и го тестваме преди пускането.
  • Комбинираме заключването с пулове, права за файлове и протоколиране в хармонична концепция за заздравяване.
  • Документираме настройките и наблюдаваме лога на грешките за подозрителни извиквания.

Как това протича като цялостен пакет, описва услугата Заздравяване на сървъри за PHP уеб сървъри.

Често задавани въпроси

Мога ли да задам disable_functions чрез ini_set() или .htaccess?

Не. Настройката действа само от php.ini или като php_admin_value във FPM пула, респективно в конфигурацията на Apache. По време на изпълнение не може да се зададе, а приложението също не може отново да отключи заключените функции.

Защитава ли disable_functions от PHP2Shell?

Не. PHP2Shell засяга самия интерпретатор на PHP, а уязвимостта се затваря само с актуализацията. Заключените функции обаче могат да ограничат пространството за действие на атакуващия след успешна експлоатация.

Защо php -i показва друг списък от моя уебсайт?

Командният ред често чете собствена php.ini. За уебсайта важи конфигурацията на PHP-FPM, mod_php или LiteSpeed. Затова проверявайте стойността в режима на работа, през който работи Вашият уебсайт.

Кои приложения се нуждаят от proc_open или exec?

Зависи от приложението. Типични са обработката на изображения чрез външни програми, генерирането на PDF, изпращането на поща през sendmail или инструменти като Composer. Проверете това в кода и в системните изисквания на производителя.

Източници

Незабавен контакт

Всеки час има значение. Пишете ни сега.

Опишете накратко системата, версията на PHP и какво сте забелязали. Ние се свързваме с Вас, уточняваме ситуацията и работим отдалечено, докато инцидентът бъде приключен и документиран.

Незабавна помощ