CVE-2026-61450 Overview
CVE-2026-61450 is a Twig sandbox bypass in the Grav flat-file content management system (CMS) affecting versions before 2.0.2. Any page author with write access to user/pages or the admin.pages role can exfiltrate the full application configuration tree. The bypass leverages the allow-listed grav.offsetGet('config') method to retrieve the raw Config object, then serializes it using allow-listed filters such as json_encode, print_r, and yaml_encode. Exposed secrets include SMTP credentials, third-party API keys, and plugin database credentials. The issue is classified as [CWE-94] Improper Control of Generation of Code and represents an incomplete fix for GHSA-j274-39qw-32c9.
Critical Impact
A low-privileged page author can extract cleartext configuration secrets, including SMTP credentials, API keys, and database credentials for installed plugins.
Affected Products
- Grav CMS versions prior to 2.0.2
- Grav installations exposing the admin.pages capability to untrusted authors
- Grav deployments where the user/pages directory is writable by non-administrative accounts
Discovery Timeline
- 2026-07-10 - CVE-2026-61450 published to the National Vulnerability Database (NVD)
- 2026-07-10 - Last updated in NVD
Technical Details for CVE-2026-61450
Vulnerability Analysis
Grav renders page content through the Twig templating engine and applies a sandbox to restrict which objects, methods, and filters authors can invoke. The sandbox was designed to block direct access to configuration internals by substituting the config variable with a redacted facade and removing Config::get and Config::toArray from the method allowlist.
The hardening is incomplete. The grav service container remains reachable inside the sandbox, and its offsetGet method is allow-listed. Calling grav.offsetGet('config') returns the live Config object rather than the redacted facade. Once the raw object is bound to a Twig variable, allow-listed serialization filters convert it to a string at the PHP level, bypassing the method gate entirely.
Root Cause
The sandbox enforces its policy at the Twig method-call boundary, not at the object graph level. Replacing the config symbol with a facade and denylisting two accessor methods does not remove alternate paths to the underlying Config instance. Because grav.offsetGet returns arbitrary container entries and PHP-level serializers walk object properties directly, the sandbox loses control the moment a live object is handed to json_encode, print_r, or yaml_encode.
Attack Vector
An authenticated author with permission to edit page content injects a Twig expression into a page template or front matter. The expression resolves the real Config object through grav.offsetGet('config') and passes it through an allow-listed dumping filter. The resulting page renders the full configuration tree, including secrets stored by third-party plugins. Exploitation requires only low privileges and no user interaction.
No verified public exploit code is currently indexed. See the GitHub Security Advisory and the VulnCheck Security Advisory for technical details.
Detection Methods for CVE-2026-61450
Indicators of Compromise
- Twig source in user/pages/**/*.md or user/pages/**/*.html.twig referencing grav.offsetGet('config'), grav['config'], or grav.config in combination with json_encode, print_r, or yaml_encode
- Rendered pages that contain plaintext values matching SMTP passwords, API tokens, or database connection strings from user/config/plugins/*.yaml
- Unexpected page edits in the Grav admin audit log by accounts holding only the admin.pages capability
Detection Strategies
- Scan the user/pages directory for Twig expressions invoking offsetGet with the argument config, plugins, or system
- Correlate content management system (CMS) authoring events with subsequent anonymous GET requests to the modified page path to detect exfiltration
- Alert on outbound HTTP responses served by Grav that contain high-entropy strings matching credential patterns
Monitoring Recommendations
- Enable Grav admin audit logging and forward events to a centralized security information and event management (SIEM) platform
- Track file integrity on user/pages, user/config, and user/plugins and alert on writes by non-administrative accounts
- Monitor web server access logs for repeated fetches of newly created or recently modified page URLs
How to Mitigate CVE-2026-61450
Immediate Actions Required
- Upgrade Grav to version 2.0.2 or later on every instance
- Rotate all secrets stored in user/config/, including SMTP credentials, API keys, and plugin database credentials, assuming compromise if untrusted authors had page write access
- Audit the admin.pages role assignments and remove the capability from accounts that do not require content publishing
Patch Information
Grav 2.0.2 removes grav.offsetGet from the sandbox allowlist for the config key and prevents serialization filters from receiving the raw Config object. Refer to the GitHub Security Advisory GHSA-mc5q-6hpj-rp7j for the full patch commit and upgrade notes.
Workarounds
- Restrict filesystem write access to user/pages to trusted administrators only until the upgrade is applied
- Disable the Grav admin plugin for accounts that do not require the admin.super capability
- Move plugin secrets out of user/config/plugins/*.yaml into environment variables referenced through ${ENV_VAR} placeholders where supported
# Upgrade Grav using the built-in CLI
bin/gpm selfupgrade -f
bin/gpm version
# Verify the installed core version is 2.0.2 or higher
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

