CVE-2026-69088 Overview
CVE-2026-69088 is a code injection vulnerability [CWE-94] in Grav CMS versions 2.0.7 through 2.0.10. The flaw resides in Blueprint::isSafeDynamicCall(), which applies its dangerous-callable denylist only to string callables that do not contain ::. Attackers with page-editing rights (admin.pages) can plant a blueprint directive that invokes arbitrary public static PHP methods with attacker-controlled arguments. Exploitation allows reading of any server-readable file and arbitrary creation or copying of files and directories under the web-server account. The issue is fixed in Grav CMS 2.0.11.
Critical Impact
A low-privileged editor account can read sensitive server files and write attacker-controlled content anywhere the web server has access, without requiring super-admin or admin.pages_twig permissions.
Affected Products
- Grav CMS 2.0.7
- Grav CMS 2.0.8 through 2.0.9
- Grav CMS 2.0.10
Discovery Timeline
- 2026-08-03 - CVE-2026-69088 published to NVD
- 2026-08-03 - Last updated in NVD database
Technical Details for CVE-2026-69088
Vulnerability Analysis
Grav CMS uses blueprint files to describe form fields, and blueprints support dynamic-field directives that resolve values at runtime by invoking PHP callables. The security gate for those callables is Blueprint::isSafeDynamicCall(), which is intended to block dangerous functions before dispatch. The check applies the denylist only when the callable string does not contain ::. Any fully-qualified static method reference of the form Class::method bypasses validation entirely and reaches the dispatch path.
An attacker holding only admin.pages can embed such a directive in a page's form-field frontmatter. When the page renders, Grav invokes the referenced static method with attacker-controlled arguments. Built-in gadget methods provide file read and file write primitives, allowing disclosure of any server-readable file to anonymous visitors and arbitrary file or directory creation under the web-server user.
Root Cause
The denylist inside Blueprint::isSafeDynamicCall() matches only bare function names. Callable strings containing the scope-resolution operator :: are treated as safe by omission, so no allowlist governs which classes or static methods may be invoked from a blueprint context.
Attack Vector
Exploitation requires a Grav administrator account limited to the admin.pages role. The attacker edits a page and injects a dynamic-field directive referencing a public static method along with attacker-chosen arguments. Rendering the page executes the method server-side and returns results, including file contents, to anyone visiting the crafted page. See the GitHub Security Advisory GHSA-7pgq-cr25-xvc8 and the Vulncheck advisory for technical details.
Detection Methods for CVE-2026-69088
Indicators of Compromise
- Page frontmatter or blueprint YAML containing dynamic directives that reference Class::method static callables that are not part of the standard Grav codebase.
- Anonymous HTTP responses on Grav pages containing contents of sensitive files such as /etc/passwd, .env, or Grav configuration under user/config/.
- New or modified files and directories under the Grav webroot that were not created by a known administrator action.
Detection Strategies
- Audit all pages and blueprints for dynamic-field directives invoking static methods, and review any callable containing :: for legitimacy.
- Review Grav admin activity logs for page edits performed by accounts holding only the admin.pages permission.
- Compare running Grav versions against 2.0.11 and flag any host reporting 2.0.7 through 2.0.10.
Monitoring Recommendations
- Alert on filesystem changes under the Grav user/pages/, user/data/, and webroot directories originating from the web-server process.
- Monitor web access logs for pages returning unusual content types or oversized responses that may indicate exfiltrated file data.
- Track PHP process activity for reads of sensitive configuration or credential files not typically accessed by the CMS.
How to Mitigate CVE-2026-69088
Immediate Actions Required
- Upgrade Grav CMS to version 2.0.11 or later on all instances.
- Rotate any secrets, API keys, or credentials that resided in files readable by the web-server account.
- Review all editor-role accounts and revoke admin.pages privileges for users who do not require them.
- Inspect existing pages and blueprints for injected Class::method directives and remove them before restoring service.
Patch Information
The vendor released the fix in Grav CMS 2.0.11. The patch extends Blueprint::isSafeDynamicCall() so its dangerous-callable checks apply to fully-qualified static method callables as well as bare function names. Details are documented in the GitHub Security Advisory GHSA-7pgq-cr25-xvc8.
Workarounds
- Restrict page-editing permissions to trusted operators until the upgrade is applied.
- Place the Grav admin interface behind network access controls or authentication proxies to limit exposure of the editor role.
- Run the PHP-FPM or web-server user with the minimum filesystem privileges necessary, preventing reads of unrelated system files.
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

