
Vérificateur de preuve de concept local uniquement pour CVE-2026-100671, reproduisant la divulgation et le rejeu du cookie de session du cache de pages Twig de Grav contre des cibles loopback.
Vérificateur minimal, local uniquement, pour la prise de contrôle de session
via le cache de contenu Twig/page de Grav, corrigée dans Grav 2.0.25.
Avis :
exploit.py est délibérément restreint aux cibles loopback :
127.0.0.1::1localhostIl refuse les hôtes distants, ne suit que les redirections loopback, utilise les clients HTTP de la bibliothèque standard Python, applique des délais d'attente aux requêtes et n'affiche jamais les jetons bearer, les cookies ou les corps de réponse.
À utiliser uniquement contre une instance Grav que vous possédez ou que vous êtes explicitement autorisé à tester. Le script crée une page de preuve publique dans le laboratoire local. Supprimez cette page après les tests si le laboratoire conserve le contenu entre les exécutions.
get_cookie() lit côté serveur le cookie de session de l'administrateur visiteur.Le compte de rédaction de page n'a besoin que du chemin d'écriture à faibles
privilèges documenté. Il n'a pas besoin de api.pages.read, admin.* ni d'un
accès super-admin. L'administrateur victime doit seulement visiter la page
publique une fois.
2.0.19 à 2.0.24 : vulnérable avec la configuration par défaut du
contenu Twig livrée.2.0.0 à 2.0.18, et 1.7.x : affecté uniquement lorsque le contenu
Twig était explicitement activé.2.0.25 : corrigé.Exécutez un laboratoire Grav local avec :
Ce dépôt à deux fichiers ne provisionne ni Grav, ni PHP, ni plugins, ni comptes.
Définissez les identifiants via des variables d'environnement afin qu'ils n'entrent jamais dans le contrôle de source :
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
L'URL de base doit rester en loopback. La route par défaut est aléatoire. Une route fixe peut être sélectionnée lors de la comparaison des exécutions :
python3 exploit.py --route /cookie-proof-24
Résultat vulnérable attendu :
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
La commande se termine avec le code 0 lorsque le résultat attendu est
reproduit, 1 lorsqu'il ne l'est pas, et 2 en cas d'erreur de configuration ou
de transport.
Exécutez la même commande contre Grav 2.0.25 :
python3 exploit.py --expect fixed
Comportement corrigé attendu : aucune valeur de session visible par l'attaquant
et aucun rejeu de session réussi. Un résultat corrigé propre se termine avec le
code 0 avec --expect fixed.
Mettez à niveau vers Grav 2.0.25 ou une version ultérieure. Pour les
déploiements plus anciens, l'avis liste ces contrôles temporaires :
security.twig_content.process_enabled: false ; ousystem.pages.never_cache_twig: true ;Ne considérez pas HttpOnly, Secure ou SameSite comme un correctif : la
lecture vulnérable du cookie se produit côté serveur pendant le rendu Twig.
Signalé par canhieu. Ce dépôt est une aide à la reproductibilité pour l'avis déjà public, et non un scanner distant ni un outil de collecte d'identifiants.