CVE-2026-42607 Overview
CVE-2026-42607 is a code injection vulnerability in Grav, a file-based PHP web platform. An authenticated administrator can achieve Remote Code Execution (RCE) by uploading a crafted ZIP archive through the Direct Install tool. Grav blocks direct .php uploads but does not inspect the contents of ZIP archives before extraction. Attackers can package malicious PHP files inside a plugin or theme archive, and the extracted code executes within the web server context. The flaw is tracked as CWE-94: Improper Control of Generation of Code and is fixed in Grav 2.0.0-beta.2.
Critical Impact
An authenticated admin can drop a persistent web shell or execute arbitrary PHP on the server, leading to full compromise of the Grav installation and the underlying host context.
Affected Products
- Grav CMS versions prior to 2.0.0-beta.2
- Grav installations exposing the Admin plugin with Direct Install enabled
- Self-hosted PHP deployments running vulnerable Grav releases
Discovery Timeline
- 2026-05-11 - CVE-2026-42607 published to NVD
- 2026-05-12 - Last updated in NVD database
Technical Details for CVE-2026-42607
Vulnerability Analysis
Grav's Direct Install tool accepts ZIP packages that represent plugins or themes. The installer rejects standalone .php uploads but treats ZIP archives as opaque containers. The archive contents are extracted to the plugin or theme directory without restricting PHP entries or validating package provenance. Once extracted, any included PHP file becomes loadable through Grav's plugin lifecycle or directly via the web server.
The upstream patch in commit 5a12f9b adds path validation to system/src/Grav/Common/GPM/Installer.php. The commit notes explicitly state the path hardening does not defend against a well-formed but malicious plugin whose PHP code is the payload; that residual trust decision now belongs to the administrator invoking directInstall.
Root Cause
The root cause is missing content inspection on uploaded archives. The Direct Install workflow assumes ZIP packages originate from trusted sources, so it neither verifies signatures nor scans entries for executable payloads. This violates [CWE-94] by allowing attacker-controlled code to enter the application's execution path.
Attack Vector
Exploitation requires valid credentials with administrative privileges over the Admin panel. The attacker crafts a ZIP that mimics a Grav plugin structure, embeds a PHP web shell or malicious bootstrap, and uploads it through Direct Install. Grav extracts the archive into user/plugins/ or user/themes/, after which the payload runs under the web server user.
// Patch excerpt: system/src/Grav/Common/GPM/Installer.php
$archive = $zip->open($zip_file);
if ($archive === true) {
// GHSA-w48r-jppp-rcfw: validate every entry name before extraction.
// ZipArchive::extractTo would otherwise honour `../` segments and
// absolute paths, letting a crafted plugin/theme ZIP write files
// anywhere the web server can reach (Zip Slip, CVE-2018-1000544
// family). Note: this hardens the path layer; it does NOT and
// cannot defend against a well-formed but malicious plugin whose
// own PHP code is the payload — that's a "trust the source"
// problem the admin must own when using directInstall.
$numFiles = $zip->numFiles;
for ($i = 0; $i < $numFiles; $i++) {
$entryName = (string) $zip->getNameIndex($i);
if (!self::isSafeArchiveEntry($entryName)) {
self::$error = self::ZIP_EXTRACT_ERROR;
$zip->close();
return false;
}
}
Folder::create($destination);
$unzip = $zip->extractTo($destination);
Source: getgrav/grav commit 5a12f9b
Detection Methods for CVE-2026-42607
Indicators of Compromise
- New or modified PHP files under user/plugins/ or user/themes/ with recent write timestamps not tied to a known release
- Admin panel audit entries referencing Direct Install followed by outbound network connections from the PHP process
- Unexpected child processes (sh, bash, python) spawned from the PHP-FPM or Apache worker servicing Grav
- Web access log entries hitting plugin paths that return executed output rather than static assets
Detection Strategies
- Monitor file integrity on the Grav user/plugins/ and user/themes/ directories and alert on PHP file creation outside maintenance windows
- Inspect web server logs for POST requests to the admin endpoint /admin/tools/direct-install correlated with subsequent requests to newly created plugin paths
- Compare installed plugin manifests against the official Grav package repository to flag sideloaded archives
Monitoring Recommendations
- Enable verbose logging of the Grav Admin plugin and forward to a centralized log platform
- Alert on PHP processes spawning shell interpreters or making outbound connections to non-allowlisted hosts
- Track administrative account usage and flag Direct Install operations performed by accounts that do not normally manage extensions
How to Mitigate CVE-2026-42607
Immediate Actions Required
- Upgrade Grav to 2.0.0-beta.2 or later, which contains the fix from GHSA-w48r-jppp-rcfw
- Audit administrator accounts, enforce strong unique passwords, and enable multi-factor authentication where supported
- Review user/plugins/ and user/themes/ for unexpected files installed since the vulnerability disclosure window
Patch Information
The vulnerability is fixed in Grav 2.0.0-beta.2. The patch is delivered in commit 5a12f9b, which validates ZIP entry names before extraction and hardens related media handling paths. Administrators must still treat plugin sources as trusted code, since the patch addresses path traversal during extraction rather than the implicit trust granted to any installed package.
Workarounds
- Disable the Direct Install tool in the Admin panel configuration until the upgrade is applied
- Restrict admin panel access to trusted IP ranges using web server ACLs or a reverse proxy
- Install plugins only from the official Grav Package Manager and block uploads of arbitrary ZIP archives at the WAF layer
# Disable Direct Install via Grav system configuration
# Edit user/config/plugins/admin.yaml
cat <<'EOF' >> user/config/plugins/admin.yaml
direct_install:
enabled: false
EOF
# Verify installed Grav version
bin/grav --version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


