
Локальный проверочный инструмент (proof-of-concept) для CVE-2026-100671, воспроизводящий раскрытие и повторное использование session-cookie из кэша страниц Grav Twig на loopback-целях.
Минимальный локальный верификатор для перехвата сессии через content-Twig/page-cache в Grav,
исправленного в Grav 2.0.25.
Рекомендации:
exploit.py намеренно ограничен loopback-целями:
127.0.0.1::1localhostОн отклоняет удалённые хосты, следует только за loopback-редиректами, использует HTTP-клиенты из стандартной библиотеки Python, применяет таймауты запросов и никогда не выводит bearer-токены, cookies или тела ответов.
Используйте только против экземпляра Grav, которым вы владеете или который вам явно разрешено тестировать. Скрипт создаёт публичную proof-страницу в локальной лаборатории. Удалите эту страницу после тестирования, если лаборатория сохраняет контент между запусками.
get_cookie() читает session cookie посещающего администратора на стороне сервера.Учётной записи для записи страниц нужен только документированный путь записи с низкими привилегиями.
Ей не нужны api.pages.read, admin.* или доступ супер-администратора. Администратору-жертве
достаточно один раз посетить публичную страницу.
2.0.19 — 2.0.24: уязвимы при поставляемой по умолчанию конфигурации content-Twig.2.0.0 — 2.0.18 и 1.7.x: затронуты только если content Twig был явно включён.2.0.25: исправлено.Запустите локальную лабораторию Grav с:
Этот репозиторий из двух файлов не разворачивает Grav, PHP, плагины или учётные записи.
Задайте учётные данные через переменные окружения, чтобы они никогда не попадали в систему контроля версий:
export GRAV_BASE_URL=http://127.0.0.1:8080
export GRAV_WRITER_USERNAME=low
export GRAV_WRITER_PASSWORD='local-writer-password'
export GRAV_ADMIN_USERNAME=admin
export GRAV_ADMIN_PASSWORD='local-admin-password'
python3 exploit.py
Базовый URL должен оставаться loopback. Маршрут по умолчанию случайный. Фиксированный маршрут можно выбрать при сравнении запусков:
python3 exploit.py --route /cookie-proof-24
Ожидаемый результат для уязвимой версии:
page_create_status=201
admin_login_status=200
victim_page_status=200
attacker_page_status=200
cached_victim_cookie_visible_to_attacker=yes
admin_cookie_value_match=yes
replayed_cookie_api_status=200
result=VULNERABLE
Команда завершается с кодом 0, когда ожидаемый результат воспроизведён, 1 — когда он не
воспроизведён, и 2 — при ошибке настройки или транспорта.
Запустите ту же команду против Grav 2.0.25:
python3 exploit.py --expect fixed
Ожидаемое поведение исправленной версии: отсутствие видимого атакующему значения сессии и
отсутствие успешного повторного использования сессии. Чистый результат для исправленной версии
завершается с кодом 0 при --expect fixed.
Обновитесь до Grav 2.0.25 или более поздней версии. Для старых развёртываний в рекомендациях
перечислены следующие временные меры:
security.twig_content.process_enabled: false; илиsystem.pages.never_cache_twig: true;Не рассматривайте HttpOnly, Secure или SameSite как исправление: уязвимое чтение cookie
происходит на стороне сервера во время рендеринга Twig.
Сообщено canhieu. Этот репозиторий — вспомогательное средство для воспроизведения уже публичной рекомендации, а не удалённый сканер или инструмент для сбора учётных данных.