highCVE-2026-53653Aug 14, 2026

CVE-2026-53653: Grav Unauthenticated DoS via Unbounded Image Resize Dimensions

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

Any anonymous visitor can crash a Grav server by requesting an image resized to extreme dimensions, which forces the server to allocate gigabytes of memory outside PHP's memory limit.

Packagegetgrav/grav
Ecosystemcomposer
Affected>= 2.0.0-beta.1, < 2.0.0-rc.8
Fixed in2.0.0-rc.8
CVE-2026-53653: Grav Unauthenticated DoS via Unbounded Image Resize Dimensions

The problem

Grav's fallbackUrl() method in system/src/Grav/Common/Grav.php loops over every URL query parameter and, when the name matches a known image action, calls it directly on the image medium with no size validation.

An attacker passes forceResize=20000,20000 (or any extreme pair) as a query string to any page that serves an image. The underlying GD library calls imagecreatetruecolor(20000, 20000), which allocates the pixel buffer via libgd outside PHP's emalloc heap, completely bypassing memory_limit.

A single request can consume over 3 GB of RAM and 20+ seconds of CPU. A handful of concurrent requests take the host offline with no account required.

Proof of concept

A working proof-of-concept for CVE-2026-53653 in getgrav/grav, with the exact payload below.

http
GET /home/test.png?forceResize=20000,20000 HTTP/1.1
Host: target.example.com

The root cause is CWE-770: no ceiling is applied to attacker-supplied dimension arguments before they are forwarded to the image library. call_user_func_array([&$medium, $action], explode(',', $params)) dispatches raw query-string integers straight into forceResize, which sets the output dimensions without clamping.

The patch (commit d9f9f03 / f4c0f42) adds a pre-dispatch guard in fallbackUrl(). It reads a new config key system.images.max_dimension (default 8000) and rejects any request where a numeric argument exceeds that ceiling, returning false before the GD call is ever made.

The cache key includes the dimensions, so varying them also bypassed the response cache on every unique request, compounding the impact.

The fix

Upgrade to Grav 2.0.0-rc.8 (or 1.7.53 for the 1.x branch). Both releases add the dimension cap in Grav::fallbackUrl(). After upgrading you can tune the ceiling with system.images.max_dimension in your system config; the default is 8000 px per side. A stricter alternative is a total-pixel ceiling (width * height) to guard against narrow-but-tall or wide-but-short bombs.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research