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

CVE-2026-62672: Grav CMS Denial of Service Vulnerability

CVE-2026-62672 is a denial of service flaw in Grav CMS allowing authenticated editors to execute catastrophic backtracking patterns. This article covers technical details, affected versions, impact, and mitigation.

Updated:

CVE-2026-62672 Overview

CVE-2026-62672 is a regular expression denial-of-service (ReDoS) vulnerability in Grav, a file-based web platform. Versions prior to 2.0.4 allowlist the regex_replace filter and function in system/config/security.yaml. The GravExtension::regexReplace() method passes an editor-controlled pattern directly to PHP's preg_replace(). When security.twig_content.process_enabled is enabled, an authenticated page editor can publish a catastrophically backtracking regex pattern. The pattern consumes PHP worker CPU and denies service to site visitors. The issue is fixed in Grav 2.0.4 and is tracked as [CWE-1333: Inefficient Regular Expression Complexity].

Critical Impact

An authenticated editor can exhaust PHP worker processes with a crafted regex pattern, rendering the site unavailable to legitimate visitors.

Affected Products

  • Grav CMS versions prior to 2.0.4
  • Grav installations with security.twig_content.process_enabled enabled
  • Sites permitting authenticated page editors to author Twig content

Discovery Timeline

  • 2026-08-19 - CVE-2026-62672 published to NVD
  • 2026-08-19 - Last updated in NVD database

Technical Details for CVE-2026-62672

Vulnerability Analysis

The vulnerability resides in the Twig regex_replace filter and function exposed by Grav's GravExtension class. Grav explicitly allowlists this filter in system/config/security.yaml, treating it as safe for use inside editor-authored Twig templates. The underlying implementation passes the pattern argument straight to PHP's preg_replace() without inspecting the expression for pathological constructs. When Twig content processing is enabled, any authenticated user with page-edit rights can embed a crafted regex into a published page. Rendering that page triggers PCRE backtracking that ties up a PHP-FPM worker for extended periods. Concurrent requests to the affected page or site quickly exhaust the available worker pool, producing a full denial of service without any memory corruption or code execution.

Root Cause

The root cause is trust of editor-controlled input as a regex pattern. GravExtension::regexReplace() invoked preg_replace($pattern, $replace, $subject, $limit) and returned the result directly. There was no timeout, no pcre.backtrack_limit failure handling, and no pattern sanitization. A pattern such as (a+)+$ applied to a long non-matching string forces exponential backtracking inside PCRE.

Attack Vector

Exploitation requires an authenticated account with permission to edit and publish page content, and an instance where security.twig_content.process_enabled is set. The attacker publishes a page containing a Twig expression that calls regex_replace with a catastrophically backtracking pattern and an adversarial subject string. Each subsequent HTTP request that renders the page consumes a PHP worker until the pool is drained.

php
     */
    public function regexReplace($subject, $pattern, $replace, $limit = -1)
    {
-        return preg_replace($pattern, $replace, $subject, $limit);
+        $result = @preg_replace($pattern, $replace, $subject, $limit);
+        if ($result === null && preg_last_error() !== PREG_NO_ERROR) {
+            // Catastrophic/backtrack-limited or invalid pattern: fail safe and leave subject unchanged.
+            return $subject;
+        }
+
+        return $result;
    }

Source: GitHub commit 9071162. The patch checks preg_last_error() and returns the original subject when PCRE reports an error such as PREG_BACKTRACK_LIMIT_ERROR, so pathological patterns fail closed instead of stalling the worker.

Detection Methods for CVE-2026-62672

Indicators of Compromise

  • Sustained high CPU usage on PHP-FPM or PHP-CGI worker processes serving Grav requests.
  • HTTP 502 or 504 responses from the reverse proxy in front of Grav during otherwise low traffic.
  • Grav pages whose Twig source contains regex_replace calls with nested quantifiers such as (a+)+, (.*)*, or (x|x)*.
  • Audit-log entries showing recent page edits by low-privilege editor accounts immediately preceding availability incidents.

Detection Strategies

  • Grep the Grav user/pages directory for Twig invocations of regex_replace or |regex_replace( and review the patterns manually.
  • Correlate PHP worker CPU spikes with recent page publish events in Grav's admin audit log.
  • Alert when a single PHP worker exceeds a CPU-time threshold (for example, one second) while handling a Grav request.

Monitoring Recommendations

  • Set pcre.backtrack_limit to a conservative value in php.ini and log preg_last_error() occurrences from application error logs.
  • Monitor PHP-FPM slowlog for requests hanging inside preg_replace.
  • Track HTTP request latency percentiles per Grav route and alert on sudden regressions after content changes.

How to Mitigate CVE-2026-62672

Immediate Actions Required

  • Upgrade Grav to version 2.0.4 or later, which contains the fail-safe wrapper around preg_replace().
  • Audit existing page content for regex_replace usage and remove or rewrite patterns authored by non-administrative users.
  • Review editor role assignments and revoke publish rights from accounts that do not require them.

Patch Information

The fix ships in Grav 2.0.4. See the GitHub release notes for 2.0.4 and GitHub Security Advisory GHSA-37f3-6p89-6qr9. The patch in commit 9071162 suppresses PCRE errors, checks preg_last_error(), and returns the original subject on failure.

Workarounds

  • Disable security.twig_content.process_enabled in system/config/security.yaml if Twig processing inside editor content is not required.
  • Remove regex_replace from the Twig filter and function allowlists in system/config/security.yaml.
  • Lower PHP's pcre.backtrack_limit so pathological patterns abort quickly, and enforce request-level execution timeouts in the web server.
bash
# Configuration example: disable Twig processing in editor content
# system/config/security.yaml
twig_content:
  process_enabled: false

# Tighten PCRE limits in php.ini
# php.ini
pcre.backtrack_limit = 100000
pcre.recursion_limit = 100000

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.