Накратко: За сигурността на php.ini най-важни са четири области: никакви съобщения за грешки навън, сигурни бисквитки на сесиите, ограничени качвания и заключени стойности, които приложенията не могат да презаписват. След PHP2Shell се добавят преходните мерки на php.net, преди всичко session.upload_progress.enabled=0. Сигурната конфигурация обаче никога не замества актуализацията.
Защо php.ini отново е във фокус след PHP2Shell
php.ini е централният конфигурационен файл на PHP. На много сървъри тя веднъж е настроена и след това почти не е пипана. С PHP2Shell това се промени: за двете уязвимости CVE-2026-109618 и CVE-2026-109619 php.net посочва преходни мерки, които се прилагат именно тук.
Самите уязвимости са в интерпретатора на PHP. Те са поправени в PHP 8.5.12, 8.4.27, 8.3.36 и 8.2.35, публикувани на 21.10.2026. Добрата конфигурация въпреки това помага по два начина: може да затрудни експлоатацията и ограничава щетите, ако все пак нещо се промъкне.
Много оператори освен това не знаят точно кои настройки важат на техния сървър. Това е първата стъпка.
Коя php.ini важи на Вашия сървър?
В зависимост от режима на работа PHP може да чете различни конфигурационни файлове. Командният ред, PHP-FPM и Apache с mod_php например при Debian и Ubuntu имат всеки собствена папка под /etc/php/<version>/. Който променя само CLI файла, не променя нищо за уебсайта.
# Конфигурационни файлове на командния ред
php --ini
# Конфигурация на PHP-FPM (адаптирайте номера на версията)
php-fpm8.3 -i | grep -E "Loaded Configuration|Scan this dir"
# Проверка на отделни стойности на PHP-FPM
php-fpm8.3 -i | grep -E "^(expose_php|display_errors|session.upload_progress.enabled) "
Освен това стойности могат да стоят във FPM пула, в конфигурацията на Apache, в .htaccess (само mod_php) или в .user.ini (FPM и CGI). Коя версия всъщност работи на сървъра и дали е включен backport, изяснява статията Как да проверите правилно версията на PHP и състоянието на пача.
Основни настройки за по-голяма сигурност на php.ini
Следните стойности са разумни за повечето продуктивни сървъри. Преди внедряване проверете в тестова среда дали Вашето приложение работи с всички стойности.
; Без информация за версията в HTTP хедъра
expose_php = Off
; Грешките да се записват в лог, но никога да не се показват в браузъра
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/error.log
; Без включване на файлове от отдалечени адреси
allow_url_include = Off
; allow_url_fopen да остане активен само ако приложението го изисква
allow_url_fopen = Off
; Сесии: стриктни, само през HTTPS, неразчитаеми от JavaScript
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
; Ограничаване на времето за изпълнение и входните данни
max_execution_time = 30
max_input_time = 60
max_input_vars = 1000
allow_url_fopen е нужна на някои приложения за актуализации или интерфейси. Изключвайте я само ако сте го проверили предварително. Функциите, които изпълняват системни команди, могат допълнително да се заключат; как става това без странични ефекти, обяснява наръчникът Правилно използване на disable_functions.
Преходни мерки на php.net за PHP2Shell
Ако не можете да пачнете веднага, php.net посочва няколко настройки, които намаляват риска. Те изрично не са пълна защита, а мост до актуализацията.
; Изключване на upload progress на сесиите (също заради CVE-2026-115560)
session.upload_progress.enabled = 0
; Ограничаване на размера на заявката: 8M без качвания, 32M с качвания
post_max_size = 8M
upload_max_filesize = 6M
; Само PHP 8.5: без backtrace при тежки грешки
fatal_error_backtraces = 0
Освен това php.net препоръчва memory_limit=-1 да се зададе така, че приложенията да не могат да презапишат стойността, а границата на паметта да се определя чрез контейнер или cgroup, не чрез RLIMIT_AS или RLIMIT_DATA. Тази мярка принадлежи във FPM пула или в конфигурацията на сървъра и трябва да се комбинира с работеща граница на cgroup. Пълния преглед ще намерите на страницата Мерки при невъзможност за пачване.
session.upload_progress.enabled=0 действа само от php.ini, FPM пул или конфигурация на сървъра. Ако е зададена чрез ini_set() или .user.ini, мярката не действа. След това рестартирайте всички worker процеси.
Заключване на стойностите срещу презаписване
Много приложения задават собствени стойности, например за памет или качвания. С php_admin_value и php_admin_flag фиксирате настройките така, че нито ini_set(), нито .user.ini да могат да ги променят. Във FPM пула това изглежда така:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (откъс)
php_admin_flag[display_errors] = off
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
php_admin_value[error_log] = /var/log/php/meine-seite.error.log
При Apache с mod_php важи същата логика с php_admin_value и php_admin_flag в конфигурацията на VirtualHost. След това презаредете услугата и проверете активната стойност:
sudo systemctl reload php8.3-fpm
# Време на стартиране на процесите: след промяната ли е?
ps -eo pid,lstart,cmd | grep "[p]hp-fpm"
Reload рестартира worker процесите на PHP-FPM. След актуализация на PHP обаче е необходим пълен рестарт на всички PHP процеси, за да не продължава да работи стар процес в паметта. При няколко уебсайта на един сървър си струва освен това отделен пул за всеки уебсайт, повече по темата в наръчника open_basedir и изолация за всеки уебсайт.
Чести грешки и кратък контролен списък
Повечето проблеми с php.ini не възникват от грешни стойности, а от стойности на грешното място. Типично е променен CLI файл, докато уебсайтът работи през PHP-FPM. Също толкова често след промяна липсва рестарт или хостинг панел презаписва собствената настройка при следващото запазване.
Втори класически случай са видимите съобщения за грешки на живия уебсайт. Те разкриват пътища, имена на бази данни или версии и улесняват ориентацията на атакуващите. Именно след преместване или нова инсталация display_errors често отново е на On.
Тези точки трябва да проверявате след всяка промяна и след всяка актуализация на PHP:
- Кой конфигурационен файл чете уеб режимът на работа и съдържа ли той Вашите стойности?
- Изключени ли са
display_errorsиexpose_phpи може ли в лога на грешките да се записва? session.upload_progress.enabledна0ли е, зададена чрез php.ini или пула?- Ограничени ли са размерите на качванията и заявките според приложението?
- Всички ли PHP процеси работят с момент на стартиране след последната промяна?
Запишете резултата с дата. Така по-късно може да се докаже коя настройка кога е важала.
Как конкретно помага PHP SOS?
- Установяваме коя конфигурация във всеки режим на работа е действително активна.
- Въвеждаме съгласувана основна конфигурация и преходните мерки за PHP2Shell, тествани с Вашето приложение.
- Заключваме свързаните със сигурността стойности срещу презаписване и рестартираме контролирано всички worker процеси.
- Документираме настройките и резултата от проверката, за да останат проследими по-късните промени.
Как изглежда трайната защита, описва услугата Заздравяване на сървъри за PHP уеб сървъри.
Често задавани въпроси
Коя php.ini всъщност ползва моят уеб сървър?
Често не е същата като в командния ред. PHP-FPM, Apache с mod_php и CLI обикновено имат собствени конфигурационни папки. Затова проверете активния файл чрез съответния режим на работа, например с php-fpm -i или с временно поставен файл за проверка.
Заменя ли сигурната php.ini актуализацията на PHP?
Не. Настройките намаляват повърхността за атака и затрудняват експлоатацията, но не затварят уязвимост в интерпретатора на PHP. Дори преходните мерки на php.net за PHP2Shell изрично не са пълна защита.
Каква е разликата между php_value и php_admin_value?
Стойностите, зададени с php_value, приложението може да промени отново по време на изпълнение. Стойностите чрез php_admin_value в FPM пула или в конфигурацията на Apache, напротив, са заключени за приложението, включително за ini_set() и .user.ini.
Трябва ли да рестартирам след промяна в php.ini?
Да. PHP-FPM и Apache с mod_php четат конфигурацията само при стартиране. Новите стойности важат едва след рестарт или reload на всички засегнати услуги.