CVE-2026-75830 Overview
CVE-2026-75830 is a path traversal vulnerability [CWE-73] in the grav-plugin-api component of the Grav content management system. The flaw affects getgrav/grav-plugin-api versions >= 1.0.0-beta.10 and <= 1.0.14. It resides in the PagesController::batchCopy() method, which fails to validate the user-controlled suffix parameter submitted via POST /api/v1/pages/batch. An incomplete fix for the prior advisory GHSA-qjq4-jp55-4mx2 left this parameter exploitable. Authenticated users holding the api.pages.write permission at editor level can supply traversal sequences to write attacker-controlled content outside the intended pages directory.
Critical Impact
Authenticated editor-level users can write arbitrary page content and page media to any filesystem location writable by the web server process, enabling code deployment and site compromise without super-admin privileges.
Affected Products
- getgrav/grav-plugin-api versions >= 1.0.0-beta.10
- getgrav/grav-plugin-api versions <= 1.0.14
- Grav CMS deployments exposing the batch pages API endpoint
Discovery Timeline
- 2026-08-18 - CVE-2026-75830 published to the National Vulnerability Database (NVD)
- 2026-08-18 - Last updated in NVD database
Technical Details for CVE-2026-75830
Vulnerability Analysis
The vulnerability resides in the PagesController::batchCopy() handler exposed through the Grav REST API. When an authenticated caller invokes POST /api/v1/pages/batch to copy pages, the controller accepts a suffix parameter used to derive the destination path. The batchCopy logic does not sanitize this parameter or reject directory traversal sequences.
A prior advisory (GHSA-qjq4-jp55-4mx2) addressed related traversal issues, but the remediation was incomplete and left the suffix field unvalidated in the batch copy path. Because the API accepts network requests and requires only editor-level authorization, exploitation reduces to a single crafted HTTP request from any account holding api.pages.write.
Root Cause
The root cause is improper limitation of a pathname to a restricted directory, tracked as [CWE-73] (External Control of File Name or Path). The suffix value is concatenated into the destination path without canonicalization or a boundary check against the intended user/pages/ directory. Traversal segments such as /../../../ collapse the path outside the pages root when the filesystem resolves the write operation.
Attack Vector
Exploitation requires an authenticated session with the api.pages.write permission — a standard editor role, not super-admin. The attacker issues a POST request to /api/v1/pages/batch invoking the copy operation and supplies a suffix value containing traversal sequences. Grav then writes attacker-controlled page content and page media to arbitrary paths writable by the web server user. Attackers can leverage this to drop PHP files into web-served directories, overwrite configuration under user/config/, or plant persistence artifacts.
No verified proof-of-concept code has been published. See the GitHub Security Advisory and the VulnCheck Advisory for vendor-supplied technical details.
Detection Methods for CVE-2026-75830
Indicators of Compromise
- HTTP POST requests to /api/v1/pages/batch where the JSON body contains suffix values including ../, ..\, or URL-encoded equivalents such as %2e%2e%2f.
- New or modified files under directories outside user/pages/ — particularly user/config/, user/plugins/, or the webroot — with ownership matching the PHP or web server process user.
- Unexpected .md, .php, or media files timestamped shortly after batch API calls from editor accounts.
Detection Strategies
- Inspect web server and application logs for requests to the batch endpoint containing traversal patterns in request bodies.
- Enable file integrity monitoring across the entire Grav installation, not only user/pages/, to catch writes into unexpected directories.
- Correlate authenticated editor sessions with subsequent filesystem changes outside their expected working directory.
Monitoring Recommendations
- Forward Grav application logs and web server access logs to a centralized analytics platform for retention and query.
- Alert on any write activity by the web server user targeting paths outside user/pages/.
- Review the population of accounts holding api.pages.write and monitor sessions from those accounts for anomalous API usage.
How to Mitigate CVE-2026-75830
Immediate Actions Required
- Upgrade grav-plugin-api to version 1.0.15 or later, which contains the corrected input validation.
- Audit all accounts holding the api.pages.write permission and revoke access from users who do not require content editing.
- Restrict network exposure of /api/v1/pages/batch to trusted management networks or place it behind a VPN.
Patch Information
The vulnerability is fixed in grav-plugin-api version 1.0.15. The patch adds validation of the suffix parameter in PagesController::batchCopy() to prevent path traversal outside the pages directory. Refer to the GitHub Security Advisory for commit-level fix details.
Workarounds
- Disable the grav-plugin-api plugin until upgrade to 1.0.15 is completed.
- Configure a reverse proxy or web application firewall rule to block requests to /api/v1/pages/batch containing .. sequences in the request body.
- Constrain filesystem permissions so the web server process cannot write outside user/pages/ and required cache directories.
# Example WAF rule pattern to block traversal in batch API payloads
# (adapt syntax to your WAF vendor)
SecRule REQUEST_URI "@streq /api/v1/pages/batch" \
"chain,phase:2,deny,status:400,id:2026075830,\
msg:'CVE-2026-75830 Grav batchCopy path traversal attempt'"
SecRule REQUEST_BODY "@rx (\.\.[\\/]|%2e%2e(%2f|%5c))" "t:lowercase,t:urlDecodeUni"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

