Executive brief
Grav is a flat-file content management system used to build websites and manage pages. A vulnerability in the Blueprint dynamic-data handler allows authenticated users (those with page-edit or blueprint-config access) to write arbitrary PHP code to files on the server, leading to remote code execution. An attacker can exploit this by crafting a malicious blueprint field that invokes the error_log function with attacker-controlled content and file paths, bypassing the intended security restrictions.
Technical details
The vulnerability is a denylist-bypass in the bare-function branch of Blueprint::isSafeDynamicCall() (Blueprint.php:530–534), which validates dynamic-data providers before execution via call_user_func_array(). While the Class::method branch uses a strict positive allowlist, the bare-function branch relies only on isDangerousFunction(), which is incomplete. The error_log() function is not in the denylist, allowing an attacker to invoke error_log($payload, 3, $filepath) to append arbitrary PHP code to a web-accessible file. An authenticated user (page-edit or blueprint-config role) can inject a malicious data directive in a blueprint to reach the sink; the paramsContainDangerousCallable() check does not block PHP payload strings, only callable references. The attacker achieves arbitrary file write and code execution without shell access.
Affected products
- Grav Grav 2.0.13 and likely other 2.x versions
Timeline
- 2026-09-17: disclosed
- 2026-09-17: advisory: GHSA-f8wv-xp27-6gq7