До основного вмісту

PHP Security: посилення безпеки через налаштування php.ini

PHP · 19.04.2026 · 4 хв читання
Ілюстрація до статті «PHP Security: посилення безпеки через налаштування php.ini»

PHP має безліч функцій, небезпечних за неправильної конфігурації. Правильне налаштування php.ini закриває цілі класи вразливостей: віддалене виконання коду (RCE), розкриття інформації про сервер, перебір файлів через обходи open_basedir. Це перший крок захисту будь-якого PHP-сервера.

Приховати інформацію про PHP

expose_php = Off
; Прибирає заголовок X-Powered-By: PHP/8.x з HTTP-відповідей

Вимкнути небезпечні функції

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,\
    curl_exec,curl_multi_exec,parse_ini_file,show_source,\
    phpinfo,posix_kill,posix_mkfifo,posix_setpgid
Деякі застосунки (скажімо, WP-CLI, Imagick) можуть потребувати частину цих функцій. Перевірте після застосування, чи все працює коректно.

Обмеження доступу до файлової системи

open_basedir = /var/www/mysite:/tmp:/usr/share/php
; Забороняє PHP читати файли за межами вказаних директорій

Вимкнути віддалені URL

allow_url_fopen = Off
allow_url_include = Off
; Блокує file_get_contents("http://...") та include з віддалених URL

Безпечні налаштування сесій

session.cookie_httponly = On
session.cookie_secure = On
session.cookie_samesite = Strict
session.use_strict_mode = On
session.use_only_cookies = On
session.gc_maxlifetime = 1440

Налаштування завантаження файлів

file_uploads = On
upload_tmp_dir = /tmp
upload_max_filesize = 64M
; Обмежте upload_tmp_dir правами www-data

Вимкнути register_globals і magic_quotes (PHP < 5.4)

; Застарілі, але перевірте у старих конфігах:
register_globals = Off
magic_quotes_gpc = Off

Чекліст безпеки PHP

  • expose_php = Off — приховати версію PHP
  • display_errors = Off — не показувати помилки відвідувачам
  • log_errors = On — записувати помилки у файл
  • allow_url_include = Off — заборонити віддалені include
  • disable_functions — вимкнути небезпечні функції
  • session.cookie_httponly = On — захист сесій
  • open_basedir — обмежити файлову систему
# Застосувати зміни
sudo systemctl reload php8.2-fpm

# Перевірка
php -r "phpinfo();" 2>&1 | grep expose_php
Використовуйте PHP Security Checker: встановіть composer require enlightn/security-checker для автоматичної перевірки відомих вразливостей у залежностях.

Реальні помилки після хардингу

Функцію вимкнено через disable_functions

Warning: shell_exec() has been disabled for security reasons in /var/www/html/deploy.php on line 22

Це попередження, а не фатальна помилка: виклик мовчки повертає NULL, виконання скрипта триває далі. Код, що не перевіряє результат shell_exec() на null, далі падає вже з іншою, менш зрозумілою помилкою — налагодження ускладнюється вдвічі.

allow_url_fopen заблокував запит

Warning: file_get_contents(http://api.example.com/data): Failed to open stream: no suitable wrapper could be found in /var/www/html/app/Api.php on line 8

Після allow_url_fopen = Off функції на кшталт file_get_contents() та fopen() перестають відкривати мережеві адреси — це очікувано й правильно, але код, що читає зовнішні API через них, потрібно переписати на cURL заздалегідь, до викочування хардингу на прод.

Порушення open_basedir

Warning: file_get_contents(): open_basedir restriction in effect. File(/etc/passwd) is not within the allowed path(s): (/var/www/mysite:/tmp:/usr/share/php) in /var/www/mysite/app/Reader.php on line 5

Це рівно та поведінка, заради якої директиву й вмикали — спроба вийти за межі дозволених шляхів блокується ще до системного виклику. Якщо легітимний код отримує цю помилку на шляхах, які мають бути доступними, — розширте перелік через двокрапку, а не вимикайте директиву повністю.

Коли хардинг ламає легітимні інструменти

  • disable_functions із proc_open та popen ламає WP-CLI, деплой-скрипти через Composer scripts і будь-які інструменти, що запускають зовнішні процеси — перевіряйте перелік використовуваних утиліт перед вимкненням.
  • Глобальний open_basedir ламає симлінки на спільні бібліотеки за межами дозволених шляхів — часта проблема при shared-vendor між кількома проектами.
  • session.cookie_secure = On без HTTPS залишить користувачів узагалі без робочих сесій — куки просто не надсилатимуться браузером.

Перевірка результату

# Версія PHP більше не світиться в заголовках відповіді
curl -I https://example.com | grep -i x-powered-by
# (порожньо — означає, що expose_php спрацював)

# Перелік фактично вимкнених функцій
php -i | grep disable_functions

# Перевірка конкретної небезпечної функції з коду
php -r "var_dump(function_exists('exec'));"

Відсутність заголовка X-Powered-By у відповіді curl — надійна ознака, що expose_php = Off застосувався. Для перевірки безпечного завантаження файлів додатково протестуйте реальне надсилання файлу через форму, а не лише налаштування php.ini.

Регулярно повторюйте цю перевірку після кожного оновлення PHP: нова мінорна версія іноді повертає директиву до значення за замовчуванням, якщо вона була задана лише в окремому модульному ini-файлі, який оновлення пакета перезаписало.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці