Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-64850

CVE-2026-64850: Grav CMS RCE Vulnerability

CVE-2026-64850 is a remote code execution flaw in Grav CMS that allows authenticated attackers to execute arbitrary commands. This post covers the technical details, affected versions, impact, and mitigation steps.

Updated:

CVE-2026-64850 Overview

CVE-2026-64850 is a code injection vulnerability in Grav, a file-based web platform. Versions prior to 2.0.7 pass an editor-controlled Class::method provider and arguments to call_user_func_array() inside Blueprint::dynamicData() without rejecting dangerous callback parameters. An authenticated user with admin.pages or api.pages.write permission can abuse Grav\Common\Utils::arrayFilterRecursive() as a trampoline with system as the callback. The attacker places a command in page frontmatter, and the command executes as the web server user when the page renders. The issue is classified as [CWE-94] Improper Control of Generation of Code and is fixed in Grav 2.0.7.

Critical Impact

Authenticated attackers with page-editing rights can achieve arbitrary command execution as the web server user, leading to full application and potentially host compromise.

Affected Products

  • Grav CMS versions prior to 2.0.7
  • system/src/Grav/Common/Data/Blueprint.php component
  • Deployments exposing admin.pages or api.pages.write permissions to untrusted editors

Discovery Timeline

  • 2026-08-19 - CVE-2026-64850 published to NVD
  • 2026-08-19 - Last updated in NVD database

Technical Details for CVE-2026-64850

Vulnerability Analysis

Grav uses blueprints to describe dynamic form data. The Blueprint::dynamicData() method resolves data providers specified in blueprint YAML by parsing a Class::method string and invoking it through call_user_func_array(). The method neither maintains an allowlist of safe providers nor rejects PHP built-ins.

An attacker with admin.pages or api.pages.write permission crafts page frontmatter that references Grav\Common\Utils::arrayFilterRecursive() as the provider. That helper walks an array and applies a caller-supplied callback to each element. By supplying system as the callback and a shell command string as the array element, the attacker turns the helper into a trampoline for command execution.

When the page is viewed, Grav evaluates the blueprint, calls the helper, and system() executes the attacker's command in the context of the web server user (typically www-data or nginx). Result: authenticated remote code execution against the Grav host.

Root Cause

The root cause is unsanitized dispatch of a user-controlled callable to call_user_func_array(). Blueprint::dynamicData() trusts the class, method, and arguments extracted from editable page frontmatter. Without an allowlist of legitimate data providers, any static method reachable through Grav's autoloader becomes callable, including helpers whose behavior is attacker-controlled.

Attack Vector

The attack requires an authenticated account with page-editing permissions. The attacker edits a page and injects frontmatter that declares a dynamic data provider pointing at Grav\Common\Utils::arrayFilterRecursive with system as the callback argument and a shell command as the data. Rendering the page triggers the callback chain and executes the command server-side.

php
 use Grav\Common\File\CompiledYamlFile;
 use Grav\Common\Grav;
 use Grav\Common\User\Interfaces\UserInterface;
+use Grav\Common\Utils;
 use RocketTheme\Toolbox\Blueprints\BlueprintForm;
 use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
 use RuntimeException;

Source: GitHub commit acffa34. The patch introduces a Utils import used to constrain the provider resolution in Blueprint::dynamicData() so that arbitrary Class::method callables can no longer be dispatched.

Detection Methods for CVE-2026-64850

Indicators of Compromise

  • Page frontmatter or blueprint YAML containing references to arrayFilterRecursive, system, exec, passthru, shell_exec, or proc_open.
  • Child processes spawned by the PHP-FPM or web server process that invoke /bin/sh, bash, or system utilities not part of normal Grav operation.
  • Unexpected outbound network connections from the Grav host immediately after a page edit or view event.
  • New or modified files in user/pages/ combined with subsequent shell activity from the web server account.

Detection Strategies

  • Inspect user/pages/**/*.md and blueprint files for Class::method provider strings referencing anything other than known Grav data providers.
  • Enable PHP disable_functions monitoring or auditd rules to log invocations of system, exec, and related functions from the web server user.
  • Correlate Grav admin audit logs of page edits with subsequent process-execution telemetry on the host.

Monitoring Recommendations

  • Alert on any process tree where the PHP or web server parent spawns a shell interpreter.
  • Monitor changes to files under user/pages/ and user/config/ and flag frontmatter that includes function names such as system or exec.
  • Track Grav admin panel authentications and API calls to api.pages.write from unexpected IPs or user agents.

How to Mitigate CVE-2026-64850

Immediate Actions Required

  • Upgrade Grav to version 2.0.7 or later, which rejects dangerous callback parameters in Blueprint::dynamicData().
  • Audit all accounts holding admin.pages or api.pages.write permissions and remove access that is not strictly required.
  • Review recent page edits and blueprint changes for suspicious Class::method provider strings and rotate any credentials or secrets accessible from the web server user if abuse is suspected.

Patch Information

The fix is available in Grav release 2.0.7. Technical details are documented in the GHSA-fj2p-qj2f-74v5 security advisory and the patch commit acffa34.

Workarounds

  • If patching cannot occur immediately, restrict admin.pages and api.pages.write to fully trusted administrators only.
  • Place the Grav admin panel behind a VPN, IP allowlist, or reverse-proxy authentication to prevent unauthenticated network exposure.
  • Configure PHP disable_functions to block system, exec, shell_exec, passthru, and proc_open where application functionality permits.
bash
# Upgrade Grav to the patched release
cd /var/www/grav
bin/gpm selfupgrade
bin/gpm update
# Verify version
bin/grav --version   # Expect: 2.0.7 or later

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.