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

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

CVE-2026-53653 is a denial of service vulnerability in Grav CMS that allows unauthenticated attackers to exhaust server resources through oversized image requests. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-53653 Overview

CVE-2026-53653 is a resource exhaustion vulnerability [CWE-770] in Grav, a file-based Web platform. Versions prior to 1.7.53 and 2.0.0-rc.8 allow an unauthenticated attacker to exhaust server memory and CPU. The flaw resides in Grav::fallbackUrl, which passes URL query parameters directly to ImageMedium magic actions without enforcing a dimension or pixel ceiling. Attackers can request image derivatives such as forceResize with oversized dimensions, forcing the server to allocate large image buffers outside PHP's memory_limit. The vendor released fixes in versions 1.7.53 and 2.0.0-rc.8.

Critical Impact

Unauthenticated remote attackers can trigger memory and CPU exhaustion on Grav servers by sending crafted image transform requests, resulting in denial of service against public web sites.

Affected Products

  • Grav CMS versions prior to 1.7.53
  • Grav CMS 2.0.0 release candidates prior to 2.0.0-rc.8
  • Any Grav-powered site exposing image assets to unauthenticated visitors

Discovery Timeline

  • 2026-07-10 - CVE-2026-53653 published to NVD
  • 2026-07-10 - Last updated in NVD database

Technical Details for CVE-2026-53653

Vulnerability Analysis

Grav supports URL-based image transforms such as image.jpg?resize=600,400 and image.jpg?forceResize=W,H. The Grav::fallbackUrl method iterates over each query parameter and, if the action name matches an entry in ImageMedium::$magic_actions, invokes the corresponding image method using call_user_func_array with the raw request parameters. No validation constrains the width, height, or resulting pixel count.

The rendering backend (GD or Imagick) allocates an output buffer sized width * height * 4 bytes. This allocation occurs at the C library level, bypassing PHP's memory_limit setting. A single request specifying dimensions such as 50000,50000 forces roughly 10 GB of RAM allocation. Repeated requests produce sustained CPU load and process termination by the operating system out-of-memory (OOM) killer.

Root Cause

The root cause is missing input validation on request-derived image transform arguments [CWE-770: Allocation of Resources Without Limits or Throttling]. Grav treated the query-string magic action pipeline as trusted developer input rather than as unauthenticated external input.

Attack Vector

Exploitation requires only network access to any image URL served by Grav. An attacker appends a magic-action query parameter with oversized numeric arguments. No authentication, session, or user interaction is required.

php
// Vulnerable code path in system/src/Grav/Common/Grav.php (pre-patch)
foreach ($uri->query(null, true) as $action => $params) {
    if (in_array($action, ImageMedium::$magic_actions, true)) {
        call_user_func_array([&$medium, $action], explode(',', (string) $params));
    }
}

// Example malicious request:
// GET /user/pages/01.home/image.jpg?forceResize=50000,50000 HTTP/1.1

Source: GitHub Commit d9f9f03

Detection Methods for CVE-2026-53653

Indicators of Compromise

  • HTTP GET requests to image assets containing query parameters matching ImageMedium magic actions such as resize, forceResize, cropResize, or crop with unusually large numeric arguments.
  • PHP-FPM or Apache worker processes terminated by the Linux OOM killer, visible in /var/log/messages or dmesg output.
  • Sudden spikes in memory usage and CPU load on Grav web servers correlated with image URL requests from a small set of source IPs.

Detection Strategies

  • Inspect web server access logs for image file extensions (.jpg, .png, .webp) accompanied by query strings containing resize=, forceResize=, or cropResize= with values exceeding typical page dimensions.
  • Alert on PHP fatal errors referencing imagecreatetruecolor, Imagick::resizeImage, or Allowed memory size in application error logs.
  • Correlate outbound 5xx response bursts on Grav endpoints with concurrent memory exhaustion events on the underlying host.

Monitoring Recommendations

  • Deploy rate limiting and anomaly detection on query-string parameters targeting image assets at the reverse proxy or WAF tier.
  • Monitor host-level metrics (RSS memory, CPU, OOM kills) alongside application logs to identify sustained resource abuse.
  • Track version fingerprints of Grav installations across the estate to identify unpatched instances.

How to Mitigate CVE-2026-53653

Immediate Actions Required

  • Upgrade Grav to version 1.7.53 or 2.0.0-rc.8 or later without delay.
  • Audit the system.images.url_actions configuration and leave it disabled unless URL-based image transforms are required.
  • If URL image actions must remain enabled, set an explicit system.images.max_pixels ceiling appropriate to the site's largest legitimate image.

Patch Information

The fix in GitHub Commit d9f9f03 and GitHub Commit f4c0f42 introduces two controls. First, URL-based magic actions are gated behind a new opt-in system.images.url_actions flag that defaults to false. Second, when the flag is enabled, a system.images.max_pixels ceiling (default 25000000, roughly 25 megapixels) rejects any request whose width multiplied by height exceeds the limit. See the GitHub Security Advisory GHSA-4x9g-vw65-vvf9, GitHub Release 1.7.53, and GitHub Release 2.0.0-rc.8.

php
// Post-patch enforcement in system/src/Grav/Common/Grav.php
if ($config->get('system.images.url_actions', false)) {
    $max_pixels = (int) $config->get('system.images.max_pixels', 25000000);
    foreach ($uri->query(null, true) as $action => $params) {
        if (in_array($action, ImageMedium::$magic_actions, true)) {
            $args = explode(',', (string) $params);
            if ($max_pixels > 0 && isset(ImageMedium::$magic_resize_actions[$action])) {
                $positions = ImageMedium::$magic_resize_actions[$action];
                $w_pos = $positions[count($positions) - 2] ?? null;
                $h_pos = $positions[count($positions) - 1] ?? null;
                $width  = ($w_pos !== null && isset($args[$w_pos]) && is_numeric($args[$w_pos])) ? (int) $args[$w_pos] : 0;
                $height = ($h_pos !== null && isset($args[$h_pos]) && is_numeric($args[$h_pos])) ? (int) $args[$h_pos] : 0;
                if ($width > 0 && $height > 0 && ($width * $height) > $max_pixels) {
                    // request rejected
                }
            }
        }
    }
}

Source: GitHub Commit d9f9f03

Workarounds

  • Block query strings containing resize, forceResize, cropResize, or other ImageMedium magic action names at the reverse proxy or WAF for image asset paths.
  • Enforce request rate limits on image URLs to reduce the impact of memory exhaustion attempts.
  • Constrain PHP-FPM worker memory using cgroup limits so a single request cannot exhaust host RAM.
bash
# Example nginx rule to strip dangerous image query parameters until patched
location ~* \.(jpg|jpeg|png|gif|webp)$ {
    if ($arg_forceResize) { return 400; }
    if ($arg_resize)      { return 400; }
    if ($arg_cropResize)  { return 400; }
    try_files $uri =404;
}

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.