getgrav/grav: Page editor can call arbitrary static methods through a renamed field in a Flex form
What fixes it
- 2.2.2getgrav/grav, composerGitHub
composer 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