CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-47706

CVE-2026-47706: Application-Level Denial of Service via Uncontrolled Recursion in Strawberry GraphQL

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 4, 2026·6 min read·11 visits

Executive Summary (TL;DR)

A recursive fragment loop triggers a RecursionError in Python, crashing worker threads/processes and resulting in complete Denial of Service.

An application-level Denial of Service vulnerability exists in the Strawberry GraphQL library (versions 0.71.0 through 0.315.6) due to uncontrolled recursion within the QueryDepthLimiter and MaxAliasesLimiter extensions when processing circular fragment references.

Vulnerability Overview

Strawberry GraphQL is an open-source Python library designed to build GraphQL APIs using type hints. The library provides optional security extensions to safeguard endpoints against resource exhaustion attacks. Two of these extensions, QueryDepthLimiter and MaxAliasesLimiter, are designed to restrict the complexity of incoming queries before execution.\n\nThese safety components are exposed to the public attack surface because they parse and validate user-supplied GraphQL queries. When an unauthenticated remote user submits a query, the validation engine processes the payload to enforce configured limits on query depth and aliases. If a query contains nested or cyclic structures, the validation logic traverses the entire document structure.\n\nA design flaw in versions prior to 0.315.7 allows an attacker to exploit the validation logic itself. By sending queries with circular fragment definitions, an attacker can bypass the safety controls and trigger an unhandled exception. This results in an application-level Denial of Service (DoS) by crashing the active Python worker thread or process.

Root Cause Analysis

The core issue is classified as CWE-674: Uncontrolled Recursion, which leads to CWE-400: Uncontrolled Resource Consumption. Within the QueryDepthLimiter extension, the determine_depth function traverses the selection sets of a GraphQL query. When the traversal encounters a FragmentSpreadNode, it retrieves the corresponding fragment definition and recursively invokes determine_depth to evaluate its inner depth.\n\nIn vulnerable versions of the library, the recursion occurred without tracking state or maintaining a history of previously visited nodes in the active path. The implementation did not pass a collection of traversed fragment identifiers down the call stack. Because of this omission, the algorithm cannot detect when it re-evaluates a fragment that is already present in its current call hierarchy.\n\nWhen a client submits a query where Fragment A references Fragment B, and Fragment B references Fragment A, a mutual recursion loop is established. The determine_depth function calls itself infinitely, executing until it consumes all available stack frames. Python runtime environments strictly limit the maximum recursion depth, throwing a RecursionError and terminating execution when the limit is breached.

Code Analysis

The fix implemented in commit a69221fb0b86583ceb5755758b294c8319021fd1 introduces path-based cycle detection using Python's immutable frozenset type. This prevents infinite loop execution by tracking the names of resolved fragments across the active execution branch. The determine_depth function was updated to accept a visited_fragments parameter.\n\npython\n# Patched version of determine_depth\ndef determine_depth(\n # ... standard parameters ...\n visited_fragments: frozenset[str] | None = None,\n) -> int:\n if visited_fragments is None:\n visited_fragments = frozenset()\n\n\nDuring traversal, when a FragmentSpreadNode is encountered, the engine checks if the fragment name already exists in the visited_fragments set. If a match is found, the function returns a depth of 0 immediately, breaking the loop safely. If the fragment is unvisited, the traversal continues, appending the current fragment name to a new frozenset using the union operator.\n\npython\n if isinstance(node, FragmentSpreadNode):\n fragment_name = node.name.value\n if fragment_name in visited_fragments:\n return 0 # Break circular recursion\n\n return determine_depth(\n node=fragments[fragment_name],\n # ... other parameters ...\n visited_fragments=visited_fragments | {fragment_name},\n )\n\n\nThis pattern is highly effective because frozenset is immutable. Using the union operator (visited_fragments | {fragment_name}) passes a distinct, branch-specific copy down the recursion tree. This avoids corrupting or sharing visited state with parallel, non-cyclic sibling query branches, ensuring both correctness and safety.\n\nmermaid\ngraph LR\n A["determine_depth(A)"] --> B["determine_depth(B)"]\n B --> C["determine_depth(A) - Triggers Break"]\n

Exploitation

An attacker can exploit this vulnerability with a single crafted HTTP POST request containing a circular fragment reference. Since the parsing and validation phases execute before any authentication middleware or resolvers, this attack does not require valid credentials. The target endpoint must have the QueryDepthLimiter or MaxAliasesLimiter extension enabled to be vulnerable.\n\nThe exploit payload defines two fragments that mutually spread each other. For example, Fragment A references B, and Fragment B references A. A top-level query then references Fragment A. When the GraphQL validation engine processes the query, it invokes the vulnerable depth limiter logic, initiating the recursive loop.\n\ngraphql\nfragment A on User {\n ...B\n}\nfragment B on User {\n ...A\n}\nquery Exploit {\n me {\n ...A\n } \n}\n\n\nOnce submitted, the worker thread begins processing determine_depth for Fragment A, which calls Fragment B, which calls Fragment A. Within milliseconds, the stack depth exceeds Python's threshold. The resulting RecursionError escapes the validation context, crashing the underlying process and denying service to other concurrent requests.

Impact Assessment

The primary impact of CVE-2026-47706 is a complete Denial of Service (DoS) of the application layer. When Python processes throw a RecursionError during query validation, the exception is frequently unhandled by the ASGI or WSGI application servers. This triggers a hard crash of the active worker process.\n\nIn standard deployments, application servers such as Gunicorn or Uvicorn maintain a fixed pool of worker processes to handle incoming requests. If an attacker sends concurrent requests containing the circular exploit payload, they can systematically crash every available worker process in the pool. This leads to a total service outage for all users.\n\nAlthough the vulnerability does not lead to remote code execution (RCE) or data confidentiality breaches, its ease of exploitation makes it a significant operational risk. Because the validation phase occurs prior to authentication, any unauthenticated user with network access to the GraphQL endpoint can trigger the crash. The CVSS score of 5.3 reflects this focused impact on service availability.

Remediation & Defensive Engineering

The primary mitigation is upgrading the strawberry-graphql package to version 0.315.7 or later. This version incorporates cycle-tracking logic into both QueryDepthLimiter and MaxAliasesLimiter to safely handle cyclic structures. Organizations should verify their dependency locks and rebuild containers to ensure the patch is applied.\n\nIf upgrading is not immediately feasible, teams can disable the QueryDepthLimiter and MaxAliasesLimiter extensions as a temporary workaround. Note that disabling these extensions will expose the application to other query complexity attacks. Therefore, this action should only be taken if alternative mitigations are implemented.\n\nAn alternative workaround involves deploying a GraphQL-aware Web Application Firewall (WAF) or an API gateway (such as Apollo Router or Envoy) at the network perimeter. The gateway can be configured to validate fragment relationships and reject queries containing circular definitions before they reach the upstream Python application servers.

Official Patches

Strawberry GraphQL Development TeamFix circular fragment parsing recursion

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Affected Systems

Strawberry GraphQL

Affected Versions Detail

Product
Affected Versions
Fixed Version
strawberry-graphql
Strawberry GraphQL
>= 0.71.0, <= 0.315.60.315.7
AttributeDetail
CWE IDCWE-674 / CWE-400
Attack VectorNetwork (AV:N)
CVSS Score5.3 (Medium)
Exploit StatusProof of Concept Available
CISA KEV StatusNot Listed
ImpactAvailability (Denial of Service)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-674
Uncontrolled Recursion

The software directs a function to call itself recursively without a mechanism to limit the recursion depth, leading to stack exhaustion.

Vulnerability Timeline

Vulnerability patched by maintainers
2026-05-19
GitHub Security Advisory and CVE Published
2026-06-04
Strawberry GraphQL Version 0.315.7 Released
2026-06-04

References & Sources

  • [1]GitHub Security Advisory GHSA-qfwv-87qj-98xq
  • [2]Strawberry GraphQL Release v0.315.7
  • [3]CVE-2026-47706 Record Database

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-84306
6.5

CVE-2026-84306: Multi-Factor Authentication Bypass via Replay Attack in Filament

A multi-factor authentication bypass vulnerability exists in Filament (Laravel full-stack framework panels) due to improper time-step tracking of Time-Based One-Time Password (TOTP) codes. By submitting valid TOTP codes from an older time window within the drift allowance, an attacker with a user's password can bypass the single-use MFA guarantee and obtain unauthorized account access.

Alon Barad
Alon Barad
2 views•7 min read
•about 2 hours ago•CVE-2026-19418
7.3

CVE-2026-19418: Broken Access Control and Cross-Site Request Forgery in TYPO3 CMS Core

CVE-2026-19418 is a high-severity origin validation vulnerability in TYPO3 CMS that enables Cross-Site Request Forgery (CSRF) and access control bypasses. Due to architectural consolidation of entry points in version 13.0, the core ReferrerEnforcer fails to isolate backend endpoints from the frontend, allowing an attacker with frontend script execution capabilities to perform unauthorized administrative actions.

Alon Barad
Alon Barad
2 views•5 min read
•about 3 hours ago•CVE-2026-84304
8.7

CVE-2026-84304: Uncontrolled Resource Consumption in gRPC-Go HTTP/2 Frame Processing

CVE-2026-84304 is a high-severity uncontrolled resource consumption vulnerability in gRPC-Go, the Go implementation of the gRPC framework. The issue stems from a memory amplification flaw inside the HTTP/2 DATA frame processing subsystem. Remote, unauthenticated attackers can exploit this vulnerability by sending a high volume of heavily fragmented, tiny DATA frames within multiplexed concurrent streams. This causes gRPC-Go servers to allocate excessive internal metadata structures on the Go heap, leading to severe heap memory amplification, intense garbage collection thrashing, and process termination due to Out-of-Memory (OOM) conditions.

Alon Barad
Alon Barad
3 views•7 min read
•about 4 hours ago•CVE-2026-79675
9.8

CVE-2026-79675: JVM Argument Injection in Natural Language Toolkit (NLTK) Stanford Wrappers

CVE-2026-79675 is a critical command injection vulnerability in NLTK versions prior to 3.10.3 that permits remote attackers to execute arbitrary code on the hosting system. This vulnerability stems from an incomplete mitigation of a previous vulnerability, CVE-2026-12841. While NLTK verified global JVM options configured through the library's setup routines, it failed to perform equivalent safety checks on options provided during per-call invocations of Stanford NLP Java wrappers. Attackers controlling these parameters can pass dangerous Java configuration options to the system shell, bypassing security boundaries to spawn interactive processes or load untrusted Java archives.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 5 hours ago•CVE-2026-73228
5.3

CVE-2026-73228: Uncontrolled Resource Consumption (DATA_UPLOAD_MAX_MEMORY_SIZE Bypass) in Django REST Framework

A vulnerability in Django REST Framework (DRF) before version 3.17.2 allows remote attackers to bypass the native Django DATA_UPLOAD_MAX_MEMORY_SIZE limits. When parsing JSON or URL-encoded request bodies, DRF's JSONParser and FormParser read directly from the low-level HTTP network stream, bypassing Django's high-level request size checks and causing Denial of Service (DoS) via resource exhaustion.

Alon Barad
Alon Barad
7 views•6 min read
•about 6 hours ago•GHSA-2RX9-3G3H-C2JV
8.1

GHSA-2rx9-3g3h-c2jv: Path Traversal Vulnerability in pacquet Lockfile Parser and Filesystem Sinks

A directory traversal vulnerability exists in pacquet, the Rust port of pnpm. When executing an install with the --trust-lockfile flag enabled, a crafted pnpm-lock.yaml file bypasses resolution-policy verification. This allows an attacker to inject path traversal sequences into package names or versions, leading to symbolic links being written outside the workspace directory.

Amit Schendel
Amit Schendel
4 views•5 min read