Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘 Packagist
Not in CISA KEV

GHSA-37f3-6p89-6qr9

Fix: getgrav/grav@9071162

GHSA-37f3-6p89-6qr9 is a CWE-1333 vulnerability in getgrav/grav. O3 Security confirms whether GHSA-37f3-6p89-6qr9 is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Grav: Authenticated ReDoS via regex_replace in Twig Sandbox

Published
Sep 2, 2026
Updated
Sep 2, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 2, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Real-World Exposure

1 pkg affected
🐘getgrav/grav

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Summary

The regex_replace filter and function are allowlisted in Grav's Twig content sandbox. When Twig processing in page content is enabled security.twig_content.process_enabled: true, authenticated page editors can supply a catastrophically backtracking PCRE pattern, causing unbounded CPU consumption and denying service to the entire web server process.


Details

The Twig sandbox allowlists, defined in system/config/security.yaml, explicitly include regex_replace in both the filter and function permission lists:

Source: system/config/security.yaml

twig_sandbox:
  allowed_filters:
    # ...
    - regex_replace    #  user-controlled pattern allowed in sandbox
  allowed_functions:
    # ...
    - regex_replace    #  same

The underlying implementation passes the caller-controlled $pattern directly into PHP's preg_replace() without any pattern complexity validation:

Source: system/src/Grav/Common/Twig/Extension/GravExtension.php:1317-1319

public function regexReplace($subject, $pattern, $replace, $limit = -1)
{
    return preg_replace($pattern, $replace, $subject, $limit);
}

When twig_content.process_enabled is true, page body content is sandboxed but can use any allowlisted filter. An editor who embeds a catastrophic backtracking pattern causes the PCRE engine to enter exponential time complexity, consuming 100% CPU until the PHP process is killed or the request times out.

Conditions required:

  1. security.twig_content.process_enabled: true (opt-in, false by default on fresh 2.0 installs)
  2. security.twig_sandbox.enabled: true (default) - the function is reachable under sandbox
  3. Attacker must have page edit access (authenticated contributor / editor role)

PoC

Configuration prerequisite - enable Twig in content:

# user/config/security.yaml
twig_content:
  process_enabled: true

Payload — embed in any Grav page body with process: { twig: true } in frontmatter:

---
title: Test
process:
  twig: true
---
{{ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab'|regex_replace('/^(a+)+$/', '') }}

Or as a function call in a page where the editor has Twig access:

{{ regex_replace('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab', '/^(a+)+$/', '') }}

Result: The PHP-FPM worker (or CLI server process) enters catastrophic PCRE backtracking. On a 2 GHz host, a 32-character string with the above pattern will exhaust one CPU core for seconds to minutes. With a slightly longer string, the time grows exponentially.


Impact

Vulnerability type: Regular Expression Denial of Service - ReDoS

Who is impacted: Server availability. Any Grav installation where:

  • An editor-role account exists (or has been compromised), AND
  • The operator has enabled twig_content.process_enabled: true

An attacker with page-edit access can render the site unresponsive for all visitors by publishing a page with a catastrophic regex. On single-worker PHP configurations this is a complete outage. On multi-worker setups, multiple concurrent page renders of the malicious page can saturate all workers.


Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistgetgrav/gravall versions2.0.4

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for getgrav/grav. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update getgrav/grav to 2.0.4 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-37f3-6p89-6qr9 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-37f3-6p89-6qr9 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-37f3-6p89-6qr9. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary The `regex_replace` filter and function are allowlisted in Grav's Twig content sandbox. When Twig processing in page content is enabled `security.twig_content.process_enabled: true`, authenticated page editors can supply a catastrophically backtracking PCRE pattern, causing unbounded CPU consumption and denying service to the entire web server process. --- ### Details The Twig sandbox allowlists, defined in `system/config/security.yaml`, explicitly include `regex_replace` in both the filter and function permission lists: **Source: `system/config/security.yaml`** ```yaml twig_
O3 Security · Impact-Aware SCA

Is GHSA-37f3-6p89-6qr9 in your dependencies?

O3 detects GHSA-37f3-6p89-6qr9 across Packagist dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-37f3-6p89-6qr9: getgrav/grav Denial of… | O3 Security