Advisory · CVE-2026-100671
Grav page cache serves a stolen admin session cookie to visitors
Grav 2.0.19 through 2.0.24 (and 1.7.x with content Twig explicitly enabled) renders page content from a page-write user through a Twig sandbox that allowlists get_cookie(), returning any cookie of the current request, including the session cookie, server-side where HttpOnly offers no protection. The finished output is stored in a page-content cache keyed without any session or user dimension. A page published by a page-write user can capture the session identifier of the next administrator who views it, and the cache then serves that identifier to unauthenticated visitors, who replay the cookie to authenticate as the administrator. Fixed in 2.0.25; 1.7.x is outside the backport scope.
- Vendor
- Grav
- Product
- Grav
- Identifier / CWE
- CVE-2026-100671
CWE-200 - Action timing
- Immediate
Explain it like I’m five
The copier prints each visitor's badge number onto the shared newsletter and pins it to the board. An attacker submits a newsletter that prints the boss's badge number; the next copy shows it to everyone, and anyone can use it as their own badge.
- 01Trap page published
A page-write user publishes a page whose Twig calls get_cookie() to read the session cookie.
- 02Admin views it
An administrator views the page; server-side rendering returns their session identifier into the content.
- 03Cache stores it
The finished output is cached without any session or user key dimension.
- 04Cookie replayed
Unauthenticated visitors are served the cached page containing the admin session identifier and replay it to authenticate as the administrator.
What happened
Grav 2.0.19 through 2.0.24 (and 1.7.x with content Twig explicitly enabled) renders page content from a page-write user through a Twig sandbox that allowlists get_cookie(), returning any cookie of the current request, including the session cookie, server-side where HttpOnly offers no protection (CVE-2026-100671, CVSS 8.6). The finished output is stored in a page-content cache keyed without any session or user dimension. A page published by a page-write user can capture the session identifier of the next administrator who views it, and the cache then serves that identifier to unauthenticated visitors, who replay the cookie to authenticate as the administrator. Fixed in Grav 2.0.25; the 1.7.x branch is outside the backport scope.
What to do
- Upgrade Grav to 2.0.25 or later (2.0.x sites; 1.7.x sites should plan a migration).
- Purge the page cache immediately after upgrading.
- Invalidate all active admin sessions and force re-authentication.
- Audit pages published by page-write users for get_cookie() or other exfiltration calls.
- Restrict page-write privileges to trusted users going forward.
Management note
Session cookies in cached public output is about as bad as it sounds: one poisoned page plus one admin pageview equals a stolen admin account. Purge the cache and kill the sessions; the upgrade alone does not clean up what is already cached.