All vulnerabilities
GHSA-9rq7-4cch-f22j

getgrav/grav: Page editor can call arbitrary static methods through a renamed field in a Flex form

getgrav/grav
CVSS
n/aHigh
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in2.2.2Fixed versionGitHub
Published5 Oct 2026Updated 5 Oct 2026GitHub

What fixes it

  • 2.2.2getgrav/grav, composerGitHubcomposer require "getgrav/grav:^2.2.2"

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Summary

A page editor can get a data-*@ directive in a page-authored Flex form past Grav's allowed-callable check by renaming the field with replace-name@. The renamed field is treated as if it came from the trusted blueprint file, so the directive can call any public static method, for example Folder::delete, Folder::move, Folder::copy or Utils::download.

Affected versions

Grav 2.0.15 through 2.2.1. Earlier releases applied the allowed-callable check to every directive regardless of where it came from, and 1.7 is not affected.

Details

Since 2.0.15, directives from file blueprints are trusted and directives from page-authored forms are held to a Class::method allowlist. Blueprint::extend() decides which incoming fields are untrusted by reading the incoming form as written. The merge that follows honours replace-name@ by moving the whole field, directive included, to a new key. That key was never marked untrusted, so Blueprint::init() gave it the base blueprint's trust and skipped the allowlist. Both Flex form builders (FlexForm, FlexDirectoryForm) extend a file-defined directory blueprint with a form from page frontmatter, which is the reachable path.

Impact

An account with page-edit permission (api.pages.write, or admin.pages in the classic admin) can call server-side methods its role does not grant, giving arbitrary directory deletion, file move or overwrite, and file read outside the page tree.

Patches

Fixed in Grav 2.2.2. replace-name@ is removed from untrusted blueprint input before it is merged, so a page-authored field always keeps its untrusted provenance.

Credits

Reported by @manus-use.

Text from GitHub Advisory Database

Affected versions 1

  • getgrav/grav, composer>= 2.0.15, < 2.2.2GitHub