
Verificatore proof-of-concept solo locale per CVE-2026-100671, che riproduce la divulgazione e il replay del cookie di sessione della cache delle pagine Twig di Grav su target loopback.
Verificatore minimale, solo locale, per la compromissione della sessione tramite content-Twig/page-cache di Grav, corretta in Grav 2.0.25.
Avvisi:
exploit.py è deliberatamente limitato a target di loopback:
127.0.0.1::1localhostRifiuta host remoti, segue solo redirect di loopback, utilizza client HTTP della libreria standard di Python, applica timeout alle richieste e non stampa mai bearer token, cookie o corpi delle risposte.
Utilizzare solo contro un'istanza Grav di propria proprietà o per cui si è esplicitamente autorizzati a eseguire test. Lo script crea una pagina di prova pubblica nel laboratorio locale. Rimuovere tale pagina dopo i test se il laboratorio conserva i contenuti tra un'esecuzione e l'altra.
get_cookie() legge lato server il cookie di sessione dell'amministratore in visita.L'account di scrittura delle pagine necessita solo del percorso di scrittura documentato a bassi privilegi. Non necessita di api.pages.read, admin.* o accesso super-admin. L'amministratore vittima deve solo visitare la pagina pubblica una volta.
2.0.19 a 2.0.24: vulnerabile con la configurazione predefinita di content-Twig fornita.2.0.0 a 2.0.18, e 1.7.x: interessate solo quando il Twig dei contenuti era esplicitamente abilitato.2.0.25: corretta.Eseguire un laboratorio Grav locale con:
Questo repository di due file non fornisce Grav, PHP, plugin o account.
Impostare le credenziali tramite variabili d'ambiente in modo che non entrino mai nel controllo di versione:
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 di base deve rimanere di loopback. La route predefinita è casuale. È possibile selezionare una route fissa quando si confrontano le esecuzioni:
python3 exploit.py --route /cookie-proof-24
Risultato vulnerabile atteso:
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
Il comando esce con 0 quando il risultato atteso viene riprodotto, 1 quando non viene riprodotto e 2 per un errore di configurazione o di trasporto.
Eseguire lo stesso comando contro Grav 2.0.25:
python3 exploit.py --expect fixed
Comportamento corretto atteso: nessun valore di sessione visibile all'attaccante e nessun replay di sessione riuscito. Un risultato corretto pulito esce con 0 con --expect fixed.
Aggiornare a Grav 2.0.25 o successivo. Per distribuzioni più vecchie, l'avviso elenca questi controlli temporanei:
security.twig_content.process_enabled: false; oppuresystem.pages.never_cache_twig: true;Non considerare HttpOnly, Secure o SameSite come una correzione: la lettura vulnerabile del cookie avviene lato server durante il rendering di Twig.
Segnalato da canhieu. Questo repository è un supporto alla riproducibilità per l'avviso già pubblico, non uno scanner remoto né uno strumento di raccolta di credenziali.