CVE-2026-85604 Overview
CVE-2026-85604 is a remote code execution vulnerability in Grav flat-file CMS versions prior to 2.0.18. The flaw resides in the Twig sort filter implementation within GravExtension.php, where the sortFunc wrapper hardcodes Twig's isSandboxed argument to false. This bypasses the sandbox protections that normally apply to filters like |map, |filter, and |reduce. An authenticated user with only page-write permissions (admin.pages or api.pages.write) can invoke spl_autoload through the sort filter, triggering a PHP include and achieving arbitrary code execution as the web server user. The vulnerability is classified under [CWE-94] Improper Control of Generation of Code.
Critical Impact
Authenticated attackers with page-write rights can achieve remote code execution as the web server user, resulting in full application compromise.
Affected Products
- Grav CMS versions <= 2.0.17
- Grav Email plugin (attack surface via form frontmatter rendering)
- Grav Admin plugin (permission surface for admin.pages)
Discovery Timeline
- 2026-09-04 - CVE-2026-85604 published to NVD
- 2026-09-08 - Last updated in NVD database
Technical Details for CVE-2026-85604
Vulnerability Analysis
Grav uses the Twig templating engine with sandbox mode enabled to restrict what authenticated content editors can execute through page templates. Most higher-order filters such as |map, |filter, and |reduce correctly propagate the sandbox flag, blocking arbitrary function invocation. The |sort filter breaks this contract. Its sortFunc wrapper in GravExtension.php calls Twig's core sort implementation with isSandboxed set to false, allowing a plain PHP function name to be passed as the sort callback while inside the sandbox.
Grav applies a denylist to restrict which functions can be called, but the list omits spl_autoload. Because spl_autoload performs a PHP include on a path derived from the supplied class name, an attacker can coerce it into loading an attacker-controlled file. When combined with a writable path within Grav (for example, uploaded page assets), this yields arbitrary PHP execution.
Root Cause
The root cause is a security control inconsistency between Twig filters combined with an incomplete function denylist. The hardcoded isSandboxed = false in sortFunc removes the sandbox check for callables, and the denylist fails to include dangerous autoloader functions such as spl_autoload.
Attack Vector
An authenticated user with the admin.pages or api.pages.write capability crafts a page containing malicious Twig markup. When rendered, for example via the Email plugin processing form frontmatter, the |sort filter invokes spl_autoload with a controlled argument. This triggers a PHP include that loads attacker-supplied code and executes it in the context of the web server process. Full technical details are available in the GitHub Security Advisory and the VulnCheck Advisory for Grav RCE.
Detection Methods for CVE-2026-85604
Indicators of Compromise
- Twig markup in page content or frontmatter containing the |sort filter with a string callback such as spl_autoload or other PHP function names.
- Unexpected PHP files written to Grav content directories (for example, user/pages/, user/data/, or upload paths) followed by web requests that render those pages.
- New or modified pages authored by low-privilege editor accounts that reference the Email plugin frontmatter with embedded Twig expressions.
- Web server processes spawning shells or outbound network connections shortly after page render events.
Detection Strategies
- Inspect Grav page markdown and frontmatter for Twig expressions invoking sort with string arguments referencing PHP functions.
- Correlate authenticated admin.pages or api.pages.write API calls with subsequent anomalous PHP execution on the host.
- Monitor file integrity for the user/ tree and flag creation of .php, .phar, or class-named files by the web server user.
Monitoring Recommendations
- Enable verbose logging in the Grav Admin plugin to capture page create and update events with author attribution.
- Forward web server, PHP-FPM, and Grav application logs to a centralized analytics platform for correlation.
- Alert on process creation events where the web server user launches interpreters, shells, or reconnaissance utilities.
How to Mitigate CVE-2026-85604
Immediate Actions Required
- Upgrade Grav to version 2.0.18 or later immediately across all environments.
- Audit user accounts holding admin.pages or api.pages.write permissions and remove access that is not strictly required.
- Review recent page edits and frontmatter for suspicious Twig expressions referencing sort, spl_autoload, or other PHP functions.
- Rotate credentials and API tokens for any account that could have been abused prior to patching.
Patch Information
The Grav maintainers released a fix in version 2.0.18 that enforces the Twig sandbox context inside sortFunc and extends the function denylist. Users should upgrade to the latest 2.x release. Refer to the GitHub Security Advisory for the authoritative patch reference and version guidance.
Workarounds
- Temporarily restrict the admin.pages and api.pages.write capabilities to trusted administrators only.
- Disable the Email plugin or any plugin that renders user-controlled frontmatter through Twig until the upgrade is applied.
- Place the Grav Admin interface behind network access controls or authentication proxies to limit exposure.
- Enforce web server user permissions that prevent writes to executable paths within the Grav installation.
# Configuration example: upgrade Grav to a patched release
cd /var/www/grav
php bin/gpm selfupgrade -f
php bin/gpm update -f
grep -R "| *sort" user/pages/ user/data/ 2>/dev/null
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

