Почему использование функций include и require с пользовательскими путями в PHP — это критическая уязвимость (LFI)?
Local File Inclusion (LFI) — одна из наиболее опасных уязвимостей в веб-приложениях на PHP. Она возникает, когда разработчик передаёт в функции include, require, include_once или require_once данные, полученные от пользователя, без надлежащей проверки и санитизации.
**Как работает уязвимость**
Представьте типичный код:
php
$page = $_GET[‘page’];
include($page . ‘.php’);
Пользователь передаёт параметр `page=about`, и сервер подключает файл `about.php`. Однако злоумышленник может передать `page=../../../../etc/passwd%00` (null-byte injection в старых версиях PHP) или `page=../../../../etc/passwd`, и сервер прочитает системный файл с учётными записями.
**Почему это критично**
1. **Чтение произвольных файлов.** Атакующий может получить доступ к конфигурационным файлам (`/etc/passwd`, `.env`, `config.php`), содержащим пароли, ключи API и другие секреты.
2. **Выполнение произвольного кода (RCE).** Если злоумышленник может загрузить файл на сервер (например, через форму загрузки изображений), а затем подключить его через LFI, это превращается в Remote Code Execution. Также атакующий может использовать PHP-обёртки: `php://input`, `php://filter`, `data://` для выполнения кода без загрузки файлов.
3. **Log Poisoning.** Атакующий внедряет PHP-код в лог-файлы сервера (например, через User-Agent), а затем подключает лог через LFI, добиваясь выполнения кода.
4. **Обход ограничений.** Использование path traversal (`../../../`) позволяет выйти за пределы веб-директории и читать любые файлы, доступные веб-серверу.
**Методы защиты**
— **Никогда не передавайте пользовательские данные напрямую** в include/require.
— Используйте **белый список** допустимых страниц:
php
$allowed = [‘about’, ‘contact’, ‘home’];
$page = $_GET[‘page’];
if (in_array($page, $allowed)) {
include($page . ‘.php’);
}
— Применяйте `basename()` и `realpath()` для нормализации пути и проверки, что итоговый путь находится в разрешённой директории.
— Отключите опасные PHP-обёртки в `php.ini`: `allow_url_include = Off`.
— Настройте `open_basedir`, чтобы ограничить доступ PHP к определённым директориям.
— Используйте статические пути — подключайте файлы по жёстко заданным именам, а не по переменным.
**Вывод**
LFI является критической уязвимостью класса A05 по OWASP Top 10 (Security Misconfiguration / Injection). Даже одна строка кода с непроверенным пользовательским вводом в include может полностью скомпрометировать сервер. Всегда валидируйте входные данные и придерживайтесь принципа минимальных привилегий.
