CVE-2017-9841
PHPUnit PHPUnit
2022-02-15
PHPUnit allows remote attackers to execute arbitrary PHP code via HTTP POST data beginning with a "<?php " substring, as demonstrated by an attack on a site with an exposed /vendor folder, i.e., external access to the /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php URI.
Технический анализ и план устранения
Суть уязвимости
Уязвимость в PHPUnit (исполнителе модульных тестов для PHP), который поставляется как зависимость в проектах. Скрипт eval-stdin.php предназначен для внутреннего использования, но если директория /vendor веб-проекта доступна извне (например, через веб-сервер), злоумышленник может отправить на этот скрипт POST-запрос с произвольным PHP-кодом. Этот код будет выполнен на сервере, что приведет к полному компрометированию системы.
Пример уязвимого пути: https://example.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Как исправить
Основное решение — удалить или заблокировать доступ к уязвимому скрипту и обновить PHPUnit.
-
Немедленно удалите или переименуйте уязвимый скрипт на всех серверах:
bash find /var/www -name "eval-stdin.php" -path "*/phpunit/*" -exec rm -f {} \;Или, если нужна осторожность, переименуйте:bash find /var/www -name "eval-stdin.php" -path "*/phpunit/*" -exec mv {} {}.disabled \; -
Обновите PHPUnit до исправленной версии. Версия зависит от вашей ветки:
- Для PHPUnit 4.x обновитесь до 4.8.35 или выше.
- Для PHPUnit 5.x обновитесь до 5.7.27 или выше.
- Для PHPUnit 6.x обновитесь до 6.5.14 или выше.
Пример для Composer (глобально или в проекте): ```bash
Для старых версий 4.x
composer require --dev phpunit/phpunit "^4.8.35"
Для версий 5.x
composer require --dev phpunit/phpunit "^5.7.27"
Для версий 6.x
composer require --dev phpunit/phpunit "^6.5.14"
Актуальная версия (рекомендуется)
composer require --dev phpunit/phpunit ```
-
Убедитесь, что директория
/vendorне доступна из веба. Настройте веб-сервер:- Для Nginx в конфиге сайта:
nginx location ~ /vendor/ { deny all; return 403; } - Для Apache в
.htaccessили конфиге виртуального хоста:apache <DirectoryMatch "/vendor/"> Require all denied </DirectoryMatch>
- Для Nginx в конфиге сайта:
Временное решение
Если немедленное обновление невозможно, выполните следующие шаги для блокировки атаки:
-
Принудительно запретите доступ к файлу
eval-stdin.phpчерез конфигурацию веб-сервера.- Nginx:
nginx location ~* eval-stdin\.php$ { deny all; return 403; } - Apache:
apache <Files "eval-stdin.php"> Require all denied </Files>
- Nginx:
-
Настройте правила WAF (Web Application Firewall):
- ModSecurity (CRS): Активируйте правило
932160, которое обнаруживает попытки удаленного выполнения кода. - Cloudflare/WAF: Создайте правило, блокирующее запросы, где в теле POST-запроса содержится
<?phpи путь включаетphpunitилиeval-stdin.
- ModSecurity (CRS): Активируйте правило
-
Временно переместите или удалите всю директорию
vendor/phpunitиз публичной веб-директории, если она там находится.