
Лаборатория на основе Docker для воспроизведения и проверки CVE-2026-28496, уязвимости инъекции шаблонов на стороне сервера в рендеринге Twig в FOSSBilling, с целями сравнения уязвимой и исправленной версий.
Этот репозиторий содержит локальную Docker-лабораторию для воспроизведения и проверки CVE-2026-28496 — уязвимости серверной инъекции шаблонов, затрагивающей поведение рендеринга шаблонов Twig в FOSSBilling.
FOSSBilling — это бесплатная платформа с открытым исходным кодом для выставления счетов и управления клиентами. Версии до 0.8.0 подвержены небезопасному поведению рендеринга шаблонов Twig, которое может выполнять переданные выражения шаблонов. FOSSBilling 0.8.0 используется в этой лаборатории в качестве исправленной цели для сравнения.
Эта лаборатория сравнивает две версии FOSSBilling:
| Сервис | Версия FOSSBilling | Назначение | URL |
|---|---|---|---|
| vuln | 0.7.2 | Уязвимая цель для сравнения | http://localhost:8081 |
| patched | 0.8.0 | Исправленная цель для сравнения | http://localhost:8082 |
Продемонстрированный путь проверки HTTP в этой локальной лаборатории:```text Unauthenticated HTTP request in this local FOSSBilling 0.7.2 lab → POST /api/system/system/string_render → JSON body contains _tpl={{ 7*7 }} → vulnerable target renders the Twig expression → patched target does not expose the same tested API behavior
В уязвимой цели вызов API возвращает:```json
{"result":"49","error":null}
В пропатченной цели тот же запрос возвращает:```json {"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
Эта лабораторная работа проверяет поведение HTTP для уязвимой и пропатченной версий, используя FOSSBilling 0.7.2 и FOSSBilling 0.8.0.
Лабораторная работа намеренно ограничена локальными Docker-сервисами. Она не нацелена на внешние системы и не включает веб-оболочки, вредоносное ПО, персистентность, внешние обратные вызовы, дампы баз данных или разрушительные полезные нагрузки.
## Проверенные факты
| Утверждение | Доказательство | Как проверить в этой лабораторной работе |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| CVE-2026-28496 затрагивает версии FOSSBilling до 0.8.0. | Публичные метаданные CVE и advisory указывают, что FOSSBilling до 0.8.0 подвержен Twig SSTI. | Изучите раздел References и сравните уязвимую и пропатченную целевые версии. |
| FOSSBilling 0.7.2 используется как уязвимая цель для сравнения. | Уязвимый сервис собирается из официального Docker-образа `fossbilling/fossbilling:0.7.2`. | Изучите `vuln/Dockerfile` и выполните `docker compose ps -a`. |
| FOSSBilling 0.8.0 используется как пропатченная цель для сравнения. | Пропатченный сервис собирается из официального Docker-образа `fossbilling/fossbilling:0.8.0`. | Изучите `patched/Dockerfile` и выполните `docker compose ps -a`. |
| Уязвимый HTTP-путь — `/api/system/system/string_render`. | Уязвимая цель возвращает JSON с `result: "49"` для `_tpl={{ 7*7 }}`. | Выполните `python3 poc/poc.py --url http://localhost:8081`. |
| Пропатченная цель не демонстрирует такое же HTTP-поведение. | Пропатченная цель возвращает `Unknown API call system/system/string_render`. | Выполните `python3 poc/poc.py --url http://localhost:8082`. |
| PoC работает только через HTTP. | `poc/poc.py` отправляет HTTP POST-запросы и не вызывает Docker, Docker Compose, shell-команды или API контейнеров. | Изучите `poc/poc.py`. |
| Лабораторная работа автоматически устанавливает обе цели FOSSBilling при запуске Docker Compose. | Одноразовые контейнеры-установщики (sidecar) завершают настройку и выходят со статусом 0. | Выполните `docker compose ps -a` и `docker compose logs installer-vuln installer-patched`. |
| Уязвимая цель отображает безвредное Twig-выражение. | HTTP-ответ с порта 8081: `{"result":"49","error":null}`. | Выполните команду PoC для уязвимой цели. |
| Пропатченная цель не отображает то же выражение через проверяемый API-путь. | HTTP-ответ с порта 8082 — ошибка JSON API с кодом `879`. | Выполните команду PoC для пропатченной цели. |
## Допущения и неизвестные
Эта лабораторная работа использует FOSSBilling 0.7.2 в качестве уязвимой цели для сравнения, поскольку публичные исследования уязвимостей указывают, что версии FOSSBilling до 0.8.0 подвержены уязвимости, а 0.7.2 — последняя уязвимая версия, использованная в протестированной цепочке.
Эта лабораторная работа использует FOSSBilling 0.8.0 в качестве пропатченной цели для сравнения, поскольку публичные метаданные advisory определяют 0.8.0 как пропатченную версию.
Эта лабораторная работа сосредоточена на наблюдаемом HTTP-поведении:```text
POST /api/system/system/string_render
с этим JSON-телом:```json {"_tpl":"{{ 7*7 }}"}
Лабораторная работа демонстрирует, что FOSSBilling 0.7.2 выполняет рендеринг переданного Twig-выражения через путь HTTP API, тогда как FOSSBilling 0.8.0 не предоставляет тот же вызов API.
Лабораторная работа не претендует на проверку всех функций рендеринга шаблонов FOSSBilling. CVE-2026-28496 также относится к другим контекстам рендеринга Twig, например к функциям рендеринга шаблонов, доступным внутри приложения.
Лабораторная работа не демонстрирует полную цепочку неаутентифицированного удалённого выполнения кода. Она проверяет неаутентифицированное HTTP-поведение, наблюдаемое на локальной цели FOSSBilling 0.7.2, и сравнивает его с FOSSBilling 0.8.0. Полная публичная цепочка включает дополнительное поведение авторизации API помимо безопасной проверки Twig-выражений, показанной здесь.
Лабораторная работа не демонстрирует:
* удалённое выполнение команд,
* извлечение учётных данных,
* дамп базы данных,
* установку расширений,
* запись произвольных файлов,
* закрепление в системе,
* загрузку веб-шелла,
* внешние обратные вызовы,
* атаки на нелабораторные системы,
* или действия после эксплуатации.
## Сводка о первопричине
Первопричина CVE-2026-28496 — небезопасный рендеринг шаблонов Twig.
FOSSBilling использует Twig для рендеринга динамических шаблонов. В уязвимых версиях переданная строка шаблона может быть передана в логику рендеринга Twig без достаточных ограничений песочницы.