CVE-2025-53833 — критичная уязвимость внедрения шаблонов на стороне сервера в LaRecipe. Уязвимы версии до 2.8.1. Рекомендуем обновиться 💣
LaRecipe — это открытый PHP-пакет, чтобы создавать документы в формате сайта. Его обычно используют для технической документации к проектам на Laravel, которые превращают Markdown-файлы в удобный веб-интерфейс с навигацией и поиском.
Метрики
Base Core: 10
CWE: CWE-1336
😬 Кратко о SSTI:
• Приложение использует шаблоны, чтобы генерировать HTML на сервере.
• Шаблонный движок поддерживает вставку переменных и выполнение функций.
• Если ввод пользователя подставляется в шаблон без фильтрации, то возможна инъекция.
• Злоумышленник может выполнить произвольный код на сервере.
В LaRecipe работает следующий механизм:
Сервер обрабатывает данные из URL запроса пользователя ⮕ компилирует
PHP-код ⮕ подставляет полученный результат в HTML разметку. Если конкретнее, он формирует дополнительные ссылки на документы. Например:
👁 Пользователь ввел:
http:/target/?test=test 👁 Сервер вернул HTML :
<a href="/user-manual/1.0?test=test#introduction">Introduction</a>😬 Суть уязвимости CVE-2025-53833:
При вводе пользователем собственного шаблона, например {{test}}, сервер вернет ошибку 500 с подобным логом:
Error: Undefined constant "test" in …/larecipe/src/Traits/HasBladeParser.php(25) : eval()'d code:4
Участок кода HasBladeParser.php(25):
try {
eval('?'.'>'.$content);
}Ошибка возникает при компиляции PHP-кода, так как переменная test не определена. Но если мы сами определим ее в шаблоне
http:/target/?{{$test=’LOL’}} — ошибки не будет, мы получит верно сгенерированный HTML. Важно, что в качестве параметра URL HTML блока, будет находится значение, которое определено нашей переменной — LOL. <a href="/user-manual/1.0?lol#introduction">Introduction</a>
Данная ошибка показывает, что компиляция происходит в функции
eval() и значения на сервере никак не валидируются. Значит, мы можем вызвать уже определенную функцию system() и выполнить RCE. Пример — на скриншоте. 💡 Важное уточнение: полезная нагрузка может передаваться не только в качестве параметра, но и в качестве его значения. Если полезную нагрузку ввести в качестве пути, сервер вернет 404.
😬 Ка защититься:
На WAF можно написать правило, которое блокирует запросы с таким содержимым:
• названия переменных содержат конструкцию
{{.*?}};• в значениях переменных также содержится
{{.*?}}. Чтобы избежать ложных сработок, например на json, включите в этот блок различные PHP-функции и операторы {{.*?(system|shell|exec|shell_exec|...|phpinfo\(\)...).*?}}.
