Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-61873

CVE-2026-61873: Grav Path Traversal Vulnerability

CVE-2026-61873 is a path traversal vulnerability in Grav CMS that allows attackers to write arbitrary files through the Form plugin. This post covers the technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-61873 Overview

CVE-2026-61873 is an arbitrary file write vulnerability in the Grav flat-file content management system (CMS) affecting versions before 9.1.8. The flaw resides in the Form plugin's process.save.filename parameter. Grav validates the parameter for path traversal sequences before Twig template processing but fails to re-validate the rendered output. Authenticated attackers can craft form submissions containing path traversal payloads that resolve after Twig rendering. Successful exploitation permits writing arbitrary files, including PHP webshells, to the web root or other sensitive locations. The issue is classified under CWE-73: External Control of File Name or Path.

Critical Impact

Authenticated attackers can write PHP webshells to the Grav web root, enabling remote code execution and full compromise of the hosting environment.

Affected Products

  • Grav CMS versions prior to 9.1.8
  • Grav Form plugin (process.save.filename handler)
  • Grav deployments exposing form submission endpoints to authenticated users

Discovery Timeline

  • 2026-07-15 - CVE-2026-61873 published to the National Vulnerability Database (NVD)
  • 2026-07-15 - Last updated in NVD database

Technical Details for CVE-2026-61873

Vulnerability Analysis

Grav is a PHP-based flat-file CMS that uses the Twig templating engine to render dynamic content. The Form plugin allows site operators to define forms whose submitted data can be saved to disk. The process.save.filename parameter controls the destination filename for saved submissions.

Grav applies path traversal validation to process.save.filename before the value is passed through Twig for rendering. Twig expressions in the filename template are then evaluated, and the rendered output is used directly as the target path. Because the post-render string is never re-validated, attackers can smuggle traversal sequences and arbitrary file extensions through Twig expressions that produce forbidden characters only after evaluation.

The resulting write primitive is bounded only by the permissions of the PHP process. Writing a .php file into the Grav web root yields remote code execution on the next HTTP request to the dropped file.

Root Cause

The root cause is order-of-operations in input sanitization. Validation occurs on the raw parameter, but the Twig engine subsequently transforms that parameter into a different string. The transformed string bypasses the earlier check because no second validation pass runs before the file write. This is a canonical [CWE-73] flaw: external control of file name or path.

Attack Vector

Exploitation requires low-privilege authenticated access sufficient to submit a form. The attacker submits a form whose process.save.filename contains a Twig expression that, after rendering, yields a path such as ../../user/pages/shell.php and body content containing PHP code. The Form plugin writes the rendered path and content without additional validation. The attacker then requests the dropped file to trigger code execution. Because the request occurs over the network with low complexity and no user interaction, the vector aligns with the network-accessible profile described in the advisory.

See the GitHub Security Advisory GHSA-q532-mvx7-42qg and the VulnCheck Advisory for Grav for the vendor and third-party technical write-ups.

Detection Methods for CVE-2026-61873

Indicators of Compromise

  • New or unexpected .php, .phtml, or .phar files appearing under the Grav user/pages/, user/data/, or web root directories
  • Form submission requests containing Twig delimiters such as {{, }}, or {% inside the process.save.filename parameter
  • Web server access logs showing GET requests to newly written PHP files immediately after a POST to a form endpoint
  • Modifications to files outside the intended user/data/<form-name>/ directory

Detection Strategies

  • Inspect HTTP POST bodies to Grav form endpoints for traversal sequences (../) or Twig syntax inside filename fields
  • Baseline the Grav content directory and alert on the creation of executable script files by the PHP or web server user
  • Correlate form submission events with subsequent file-creation events and outbound network activity from the web server process

Monitoring Recommendations

  • Enable file integrity monitoring on the Grav installation directory, particularly user/pages/, user/data/, and the document root
  • Forward web server access logs and PHP error logs to a centralized analytics platform for retention and query
  • Monitor for anomalous child processes spawned by the PHP-FPM or web server process, which often follow webshell execution

How to Mitigate CVE-2026-61873

Immediate Actions Required

  • Upgrade Grav to version 9.1.8 or later on all affected instances without delay
  • Audit the Grav content and web root directories for unauthorized PHP files created since the deployment of the vulnerable version
  • Rotate administrator credentials and API tokens if compromise is suspected, since low-privilege accounts are sufficient for exploitation
  • Review Form plugin definitions and remove any templates that expose process.save.filename to untrusted input

Patch Information

The Grav maintainers addressed CVE-2026-61873 in Grav 9.1.8 by re-validating the rendered filename after Twig processing. Refer to the GitHub Security Advisory GHSA-q532-mvx7-42qg for the official fix commit and upgrade guidance.

Workarounds

  • Restrict access to form submission endpoints using authentication proxies or IP allowlisting until patching is complete
  • Configure the web server to deny execution of PHP files in user/data/ and other writable directories
  • Run the PHP process under a least-privilege account with write access limited to directories that are not web-executable
bash
# Example nginx configuration to block PHP execution in Grav data directories
location ~ ^/user/(data|pages)/.*\.(php|phtml|phar)$ {
    deny all;
    return 403;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.