CVE-2026-58654 Overview
CVE-2026-58654 is an unrestricted file upload vulnerability in the Grav API plugin (getgrav/grav-plugin-api) version 1.0.0. The flaw resides in the avatar upload endpoint at /api/v1/users/user/avatar. The endpoint validates only the client-declared MIME type using getClientMediaType and accepts any value beginning with image/. It does not inspect file content or restrict the stored extension. An authenticated user can persist PHP code, SVG files with embedded JavaScript, or polyglot payloads under user/accounts/avatars/ with predictable filenames. The issue is tracked under [CWE-434] and fixed in version 1.0.1.
Critical Impact
Authenticated attackers can store arbitrary file content on disk, creating a foothold for remote code execution or stored cross-site scripting when combined with a path traversal flaw or server misconfiguration.
Affected Products
- Grav API plugin (getgrav/grav-plugin-api) version 1.0.0
- Grav CMS installations exposing the API plugin avatar endpoint
- Fixed in Grav API plugin version 1.0.1
Discovery Timeline
- 2026-07-08 - CVE-2026-58654 published to NVD
- 2026-07-08 - Last updated in NVD database
Technical Details for CVE-2026-58654
Vulnerability Analysis
The Grav API plugin exposes an avatar upload endpoint intended to accept user profile images. The server-side validation logic checks only the MIME type declared by the HTTP client through getClientMediaType. Any value with the prefix image/ is accepted. An attacker can send a request declaring Content-Type: image/png while attaching a file containing PHP source, SVG markup with JavaScript, or a polyglot payload combining multiple formats.
The plugin then writes the file to user/accounts/avatars/ using a predictable filename derived from the account. The stored file preserves the attacker-supplied extension because the plugin does not normalize or restrict extensions. A default .htaccess file in the avatars directory blocks direct HTTP retrieval and returns HTTP 403. The malicious content still resides on disk and remains reachable through any secondary flaw that bypasses the directory restriction.
Root Cause
The root cause is reliance on client-controlled metadata for security decisions [CWE-434]. The plugin trusts the Content-Type header sent with the multipart upload and never performs magic-byte inspection, extension allowlisting, or image re-encoding. Filename predictability compounds the issue by giving attackers a known target path.
Attack Vector
Exploitation requires an authenticated session on the Grav instance. The attacker submits a crafted multipart POST request to /api/v1/users/user/avatar with a spoofed MIME type and a payload file. The server writes the file without content inspection. Direct execution is blocked by .htaccess, so the attacker must chain the primitive with a path traversal vulnerability, a misconfigured web server that ignores .htaccess, or an application feature that reads the avatar file into a rendering context vulnerable to script execution.
See the GitHub Security Advisory and the VulnCheck Advisory on Grav for additional technical detail.
Detection Methods for CVE-2026-58654
Indicators of Compromise
- Files under user/accounts/avatars/ with non-image extensions such as .php, .phtml, .svg, or double extensions like .jpg.php.
- HTTP 403 responses in access logs for requests targeting avatar file paths, indicating attempted retrieval of planted content.
- Unexpected POST traffic to /api/v1/users/user/avatar from accounts that do not normally update profile images.
Detection Strategies
- Perform periodic file integrity checks on user/accounts/avatars/ and alert on any file whose magic bytes do not match a supported image format.
- Inspect web server access logs for uploads to the avatar endpoint followed by direct access attempts to files in the avatars directory.
- Correlate authenticated session activity with file writes under the Grav data directory to surface abnormal upload patterns.
Monitoring Recommendations
- Enable verbose logging on the Grav API plugin and forward access logs to a centralized analytics platform for retention and search.
- Monitor the avatars directory with filesystem auditing to capture file creation events with process context.
- Track authentication events tied to avatar uploads and flag repeated uploads from a single account within short intervals.
How to Mitigate CVE-2026-58654
Immediate Actions Required
- Upgrade the Grav API plugin to version 1.0.1 or later, which enforces server-side content validation.
- Audit user/accounts/avatars/ for files with non-image extensions or embedded scripting content and remove any malicious artifacts.
- Verify that the protective .htaccess file in the avatars directory is present and honored by the web server configuration.
Patch Information
The maintainers released Grav API plugin version 1.0.1 to address CVE-2026-58654. The fix adds server-side validation of uploaded content and restricts the resulting file extension. Refer to the GitHub Security Advisory GHSA-xc64-vh46-vph6 for the full advisory and patch commit.
Workarounds
- Disable the avatar upload endpoint at the reverse proxy layer until the patched plugin version is deployed.
- Restrict access to the Grav API plugin to trusted administrative accounts and review the user population for stale or unused accounts.
- Confirm that the web server processes .htaccess directives and that PHP execution is disabled for the user/accounts/avatars/ directory.
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

