CVE-2026-42845 - Grav Form Plugin has an Anonymous Page Content Overwrite via Form File Upload fi
CVE-2026-42845 - Grav Form Plugin has an Anonymous Page Content Overwrite via Form File Upload fi
GHSA-w4rc-p66m-x6qq HIGH composer/getgrav/grav-plugin-form
CVE: CVE-2026-42845
Summary
(Tested on Form 9.0.3 released on April, 28th)
The Form plugin's file upload handler at user/plugins/form/classes/Form.php:583 accepts a POST-supplied filename parameter ($filename = $post['filename'] ?? $upload['file']['name']) that overrides the original uploaded filename. The override passes through Utils::checkFilename(), which blocks only a narrow extension list (.php*, .htm*, .js, .exe). Markdown (.md) is not blocked.
A page's directory under user/pages/ contains its .md content file (e.g. default.md, form.md). When a form's file upload field has accept: ['*'] (or any policy that admits text files), an unauthenticated visitor can:
1. Upload arbitrary content with filename=form.md (or other page-content filenames),
2. Submit the form to trigger Form::copyFiles(), which overwrites the page's own .md file.
Details
Vulnerable code path
user/plugins/form/classes/Form.php:580-606 (in uploadFiles()):
$grav->fireEvent('onFormUploadSettings', new Event(['settings' => &$settings, 'post' => $post]));
$upload = json_decode(json_encode($this->normalizeFiles($_FILES['data'], $settings->name)), true);
$filename = $post['filename'] ?? $upload['file']['name']; // ← POST-controlled
// ...
if (!Utils::checkFilename($filename)) { // ← extension blocklist only
return ['status' => 'error', 'message' => 'Bad filename'];
}Utils::checkFilename() (system/src/Grav/Common/Utils.php:980) blocks .., slashes, null bytes, leading/trailing dots, and the uploads_dangerous_extensions list. The default list contains: php, php2-5, phar, phtml, html, htm, shtml, shtm, js, exe. md is not on the list.
The MIME check (lines 627-654) uses Utils::getMimeByFilename($filename) against the blueprint's accept list. With accept: ['*'], all filenames pass.
After upload, the file is held in flash storage. When the form is submitted, Form::copyFiles()
📌 来源: GitHub-Advisory | 🆔 CVE-2026-42845 | 📅 2026-05-06