Skip to content
Security·2026-04-23·Tommes Parzl

GraphQL-Alias-Batching: wie ein Request 200 Mutations packt

Cloudflare zählt HTTP-Calls, GraphQL-Resolver sind innerhalb eines Requests meist nicht rate-limited. Das ist keine Schwäche von Cloudflare, sondern ein Muster das Security-Teams oft übersehen. Hier der Pattern, die Exploits, und die einzige saubere Mitigation.

graphqlrate-limitingweb-security

Das Muster in einem Satz

Wenn deine API-Gateway-Schicht Rate-Limits auf HTTP-Request-Ebene enforced und dein GraphQL-Server die Anzahl der operations pro Request nicht separat gegenprüft, kann ein Angreifer mit einem einzigen Request mehrere hundert Mutations ausführen.

Das ist kein exotischer Angriff. GraphQL-Alias-Syntax erlaubt es per Design:

mutation {
  a1: submitVote(option: "yes") { ok }
  a2: submitVote(option: "yes") { ok }
  a3: submitVote(option: "yes") { ok }
  # ... bis a200
}

Ein Request. Ein HTTP-Call. 200 Resolver-Ausführungen.

Warum das so oft unbemerkt ist

Drei Gründe:

  1. Cloudflare-Rules sehen nur HTTP-Request-Anzahl. Der Gateway-Layer prüft URL-Pattern, Header, Method, Source-IP. Der Body bleibt opaque.
  2. GraphQL-Server gehen davon aus, dass der Gateway vor ihnen ist und das regelt. Die Resolver-Implementation vertraut darauf, dass Rate-Limiting schon auf Netzwerk-Ebene passiert ist.
  3. Developer-Tests verwenden meist ein Operation pro Request. Die Alias-Pattern-Edge-Case taucht in Unit-Tests selten auf.

Konkrete Exploit-Klassen

  • Rate-Limit-Bypass auf sensitive Mutations: Password-Reset, OTP-Generation, Credit-Application-Submit. Wenn ein Request 200 dieser Mutations enthält, bekommt ein Angreifer in einem Schuss soviel Output wie normalerweise in Stunden.
  • Brute-Force-Enumeration: Mutations die existierende vs nicht-existierende User per differential Error-Response signalisieren. Aliases erlauben 200 parallele Checks in einem Request.
  • Credit/Balance-Race-Conditions: Wenn eine Mutation intern Balance erhöht und Deduplication fehlt, lassen sich Race-Windows innerhalb eines Requests öffnen.

Die einzige saubere Mitigation

Rate-Limiting innerhalb des GraphQL-Servers, nicht am Gateway:

  • Operation-Depth-Limit setzen (z. B. max 5)
  • Operation-Count-pro-Request limitieren (meist 1-3 für Mutations, mehr nur für Queries)
  • Pro Field/Resolver ein Semaphore das pro User-Session kount, nicht pro HTTP-Request
  • Eine gute Library dafür ist graphql-shield mit rate-limit-Middleware oder selbst gebaut mit Redis-Counter

Was du heute tun kannst

  1. Greife in deinem GraphQL-Schema nach allen mutation-Fields und prüfe: würde eine 100x-Alias-Ausführung in einem Request etwas nicht-idempotentes 100x auslösen?
  2. Wenn ja → Operation-Count-Limit einbauen. Typisch: max 5 Mutations pro Request.
  3. Für alle verbleibenden Mutations: Rate-Limit pro User-Session (nicht pro IP, nicht pro Request). Redis-Zähler mit Sliding-Window.

Referenz

Wir haben dieses Muster 2026 bei einem Tier-1-Marketplace in einer Session-Audit-Engagement gefunden und responsible disclosed. Die Mitigation-Empfehlung mit graphql-shield-Rules wurde innerhalb 48 Stunden implementiert. Finding-Pattern ist ein wiederkehrender Klassiker, kein Einzelfall.

Bereit für eine echte Bewertung?

Kurzes Scoping-Gespräch, klares Angebot, Start in zwei bis vier Wochen.

Gespräch anfragen

Newsletter

Substance über Schnee

Ein Mail alle zwei Wochen mit einem neuen Blog-Post oder einem technischen Deep-Dive. Kein Clickbait.