
Verificador de prueba de concepto local para CVE-2026-100671, que reproduce la divulgación y repetición de cookies de sesión de la caché de páginas de Grav Twig contra objetivos de loopback.
Verificador mínimo, solo local, para la toma de control de sesión mediante Twig de contenido/caché de páginas de Grav, corregida en Grav 2.0.25.
Avisos:
exploit.py está deliberadamente restringido a objetivos de loopback:
127.0.0.1::1localhostRechaza hosts remotos, sigue únicamente redirecciones de loopback, utiliza clientes HTTP de la biblioteca estándar de Python, aplica tiempos de espera en las solicitudes y nunca imprime tokens de portador, cookies ni cuerpos de respuesta.
Úsalo solo contra una instancia de Grav que poseas o que estés explícitamente autorizado a probar. El script crea una página de prueba pública en el laboratorio local. Elimina esa página después de las pruebas si el laboratorio conserva contenido entre ejecuciones.
get_cookie() lee del lado del servidor la cookie de sesión del administrador visitante.La cuenta de escritura de páginas solo necesita la ruta de escritura de bajos privilegios documentada. No necesita api.pages.read, admin.* ni acceso de superadministrador. El administrador víctima solo necesita visitar la página pública una vez.
2.0.19 hasta 2.0.24: vulnerable con la configuración predeterminada de Twig de contenido incluida.2.0.0 hasta 2.0.18, y 1.7.x: afectadas solo cuando Twig de contenido estaba habilitado explícitamente.2.0.25: corregida.Ejecuta un laboratorio local de Grav con:
Este repositorio de dos archivos no aprovisiona Grav, PHP, plugins ni cuentas.
Establece las credenciales mediante variables de entorno para que nunca entren en el control de código fuente:
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
La URL base debe permanecer en loopback. La ruta predeterminada es aleatoria. Se puede seleccionar una ruta fija al comparar ejecuciones:
python3 exploit.py --route /cookie-proof-24
Resultado vulnerable esperado:
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
El comando sale con 0 cuando se reproduce el resultado esperado, 1 cuando no se reproduce, y 2 para un error de configuración o de transporte.
Ejecuta el mismo comando contra Grav 2.0.25:
python3 exploit.py --expect fixed
Comportamiento corregido esperado: ningún valor de sesión visible para el atacante y ninguna reproducción de sesión exitosa. Un resultado corregido limpio sale con 0 con --expect fixed.
Actualiza a Grav 2.0.25 o posterior. Para implementaciones más antiguas, el aviso enumera estos controles temporales:
security.twig_content.process_enabled: false; osystem.pages.never_cache_twig: true;No trates HttpOnly, Secure o SameSite como una corrección: la lectura vulnerable de la cookie ocurre del lado del servidor durante el renderizado de Twig.
Reportado por canhieu. Este repositorio es una ayuda de reproducibilidad para el aviso ya público, no un escáner remoto ni una herramienta de recolección de credenciales.