GraphQL-API-Sicherheitsrisiken, die jedes Entwicklungsteam kennen sollte

Wiz Expertenteam
Das Wichtigste auf einen Blick
  • GraphQL-API-Sicherheit ist die Praxis, Backends gegen GraphQL-spezifische Schwachstellen und Risiken zu verteidigen.

  • Im Vergleich zu REST sind GraphQL-APIs besonderen Risiken ausgesetzt, etwa übermäßiger Abfragekomplexität, Datenüberexposition durch zu freizügige Feldauswahl, Injection-Angriffen und dem Missbrauch der Schema-Introspection. GraphQL-Backends sind zudem anfällig für IDOR-Angriffe, Denial-of-Service-Risiken, Schema-Offenlegung und Herausforderungen beim Rate-Limiting.

  • Zu den Best Practices für GraphQL-API-Sicherheit zählen Autorisierung auf Feldebene, Whitelisting von Abfragen, Grenzen für die Abfragetiefe, dedizierter CSRF-Schutz, das Deaktivieren der Introspection und eine Query-Cost-Analyse.

  • GraphQL-Sicherheitslücken lassen sich mindern, indem die API über ihren gesamten Lebenszyklus geschützt wird. Für umfassenden Schutz eignet sich am besten eine All-in-one-Cloud-Sicherheitsplattform wie Wiz.

Was ist GraphQL-API-Sicherheit?

GraphQL-API-Sicherheit umfasst spezialisierte Verfahren und Kontrollen zum Schutz von GraphQL-Endpoints. Im Mittelpunkt steht die Minderung von Risiken und Schwachstellen, die aus der flexiblen Natur und der besonderen Architektur von GraphQL entstehen: etwa Over-Fetching, übermäßige Abfragekomplexität, Injection-Probleme, der Missbrauch der Schema-Introspection und das Ausnutzen der Abfragetiefe.

Was GraphQL-Sicherheit besonders macht

Im Gegensatz zu RESTful-APIs, die meist ressourcenorientiert arbeiten, ist GraphQL schemagesteuert und baut auf den folgenden Kernkomponenten auf:

  • Schemas: Baupläne, die die Struktur der Daten und die für Clients möglichen Operationen festlegen;

  • Resolver: Funktionen, die Daten für bestimmte Schemafelder lesen, erstellen, aktualisieren oder löschen;

  • Queries, Mutations und Subscriptions: die zentralen Operationen, um Daten abzurufen, zu verändern oder Push-Updates zu empfangen.

GraphQL-Funktionen werden in der Regel über einen einzigen HTTP-Endpoint bereitgestellt (z. B. https://api.yourdomain.com/api/graphql), der oft POST unterstützt (und manchmal GET für Queries oder Persisted Queries) und clientgesteuerte Abfragen im Request enthält. Der Inhalt des Request-Body bestimmt dann, wie die Daten gemäß dem Schema gelesen oder verändert werden.

Diese extrem flexiblen Abfragemöglichkeiten sind ein großer Vorteil, bringen aber auch Sicherheitsherausforderungen mit sich. Da das Modell eine unbegrenzte Zahl gültiger Eingabeabfragen zulässt, lässt es sich ausnutzen, wenn es nicht sauber kontrolliert wird.

Das Fazit: GraphQL erfordert technische Schutzmaßnahmen, die über gängige Best Practices für die Sicherheit von REST-APIs hinausgehen. Bevor der Blick auf die Schutzmaßnahmen fällt, folgt zunächst eine genauere Betrachtung der Angriffsvektoren.

Zentrale GraphQL-Schwachstellen und Angriffsvektoren

OWASP, GraphQL.org und Apollo benennen dringende Sicherheitsrisiken, die GraphQL-APIs betreffen:

Autorisierungsprobleme

In GraphQL lassen sich Abfragen frei gestalten. Diese vielseitige Abfragestruktur erschwert jedoch die Umsetzung von role-based access control (RBAC) stärker als bei klassischen REST-APIs.

Ohne strikte Autorisierung auf Feldebene können sensible Informationen offengelegt werden, selbst wenn übergeordnete Zugriffsregeln greifen. Ein Beispiel: Ein Nutzer darf sein Profil abfragen, könnte aber weiterhin auf verborgene Felder wie role zugreifen oder sie manipulieren, wenn diese nicht eingeschränkt sind.

Diese Freiheit beim Datenabruf schafft außerdem einen Nährboden für Angriffe über insecure direct object reference (IDOR). Ein gängiges GraphQL-Muster nutzt nämlich ein Feld auf Root-Ebene, das einen Identifier (etwa eine id) annimmt, um ein bestimmtes Objekt abzurufen. Zum Beispiel:

query GetCompanyDetails($companyId: ID!) {
  company(id: $companyId) {
    name
    email
  }
}

Was passiert, wenn der Resolver für das Feld company keine ordentlichen Autorisierungsprüfungen erzwingt? Ein Angreifer könnte die $companyId von seinem autorisierten Wert (z. B. 100) auf einen anderen Wert (z. B. 101) erhöhen und so auf Daten zugreifen, für die er keine Berechtigung hat.

Denial-of-Service-Bedrohungen

Ein weiteres großes Risiko: Die Flexibilität von GraphQL lässt sich für denial-of-service (DoS)-Versuche missbrauchen:

  • Angreifer können absichtlich zu tief verschachtelte Abfragen oder Abfragen mit zirkulären Abhängigkeiten erzeugen, die übermäßig viele Resolver-Aufrufe auslösen. Das Ergebnis ist ein überlasteter Server, der seine Ressourcen schnell erschöpft;

  • Query-Batching kann naive Rate-Limiter aushebeln, weil böswillige Nutzer mehrere aufwendige Operationen in einem einzigen Request bündeln. Da GraphQL-Backends meist nur einen einzigen Endpoint bereitstellen, ist ein wirksames Rate-Limiting schwer umzusetzen;

  • Angreifer können auch Alias-basierte Amplification ausnutzen und wiederholte, teure Operationen hinter unterschiedlichen Feld-Aliasen verstecken;

  • Eine weitere Taktik sind sogenannte „Complexity-Bomb“-Abfragen. Dabei studieren Angreifer das öffentliche GraphQL-Schema, um Abfragen zu bilden, die oberflächlich einfach wirken, im Backend aber hohe Rechenlast verursachen.

Schema-Introspection und Datenüberexposition

Über die Introspection-Funktion lassen sich spezielle Abfragen schreiben, um das Schema der GraphQL-API zu erkunden, etwa verfügbare Typen, Felder und Operationen. Das hilft Entwicklungsteams – und schafft zugleich einige GraphQL-Schwachstellen.

Böswillige Akteure können Introspection-Abfragen leicht für Schema-Discovery-Angriffe missbrauchen, um private Datentypen, undokumentierte Felder, administrative Funktionen und mehr aufzudecken. Sie schreiben gezielte Abfragen, die Datenlecks, Denial-of-Service-Angriffe und andere Exploits auslösen.

Wichtig zu bedenken: Die Offenlegung personenbezogener Daten kann zu einem erheblichen Compliance-Problem werden. Verstöße gegen Datenschutzvorschriften wie die DSGVO und den CCPA können hohe Bußgelder nach sich ziehen.

Informationslecks durch Fehlerbehandlung

Wie bei REST-APIs können auch GraphQL-Endpoints durch unsaubere Fehlerbehandlung ungewollt sensible Informationen preisgeben. Bei einer ungültigen Abfrage gibt ein schlecht konfigurierter Server möglicherweise ausführliche Fehlermeldungen zurück, die den zugrunde liegenden Tech-Stack oder Teile des Schemas verraten.

Eine Fehlermeldung wie "Cannot query field 'userRole' on type 'Query'. Did you mean 'role'?" offenbart beispielsweise die Existenz des Feldnamens role. Ebenso deckt ein Fehler wie "Cannot query field 'salary' on type 'User'" die Existenz eines Felds salary auf, selbst wenn der Zugriff darauf eingeschränkt ist.

Angreifer, die Schwächen in der Fehlerbehandlung entdecken, senden automatisierte, zufällige Abfragen und analysieren die Fehlerantworten, um so viel wie möglich über das GraphQL-Schema herauszufinden – und nutzen das Gelernte anschließend gegen das Ziel.

GraphQL-Injection-Angriffe

Wegen seiner offenen Eingabestruktur ist GraphQL besonders anfällig für klassische Injection-Angriffe. Tatsächlich zählen Injection-Angriffe zu den am häufigsten dokumentierten GraphQL-Sicherheitsvorfällen.

Die Möglichkeit der Nutzer, Abfrageeingaben zu steuern, öffnet die Tür für zahlreiche Probleme, darunter:

  • SQL-Injection: Sie tritt auf, wenn ein Argument direkt in einen Datenbank-Query-String eingefügt wird. Zur Vorbeugung empfehlen sich stets parametrisierte Abfragen oder Prepared Statements statt String-Verkettung;

  • Command-Injection: Sie entsteht, wenn ein Resolver eine vom Nutzer gelieferte Zeichenkette verwendet, um einen Systembefehl auf dem Server auszuführen. Dieses Risiko lässt sich verringern, indem man direkte Shell-Aufrufe vermeidet und Eingaben gegen strikte Whitelists prüft;

  • prompt injection: Dabei wird eine vom Nutzer gelieferte Eingabe in dynamisch erzeugte KI-Prompts eingefügt, um deren beabsichtigtes Verhalten zu verändern. Dieses Problem lässt sich mindern, indem man Nutzereingaben von Systemanweisungen trennt, Eingaben bereinigt und guardrails einsetzt, die den Handlungsspielraum der KI begrenzen.

CSRF bei Mutation-Operationen

cross-site request forgery (CSRF) liegt vor, wenn eine bösartige Website einen Browser dazu verleitet, unbeabsichtigte Aktionen auf einer vertrauenswürdigen Seite auszuführen, auf der der Nutzer bereits angemeldet ist. Diese GraphQL-Schwachstelle betrifft häufig Mutation-Operationen, doch auch Query-Operationen, die in fehlerhaft konzipierten Systemen Nebenwirkungen auslösen, lassen sich missbrauchen.

GraphQL-Backends sind besonders anfällig für CSRF, weil sie einen einzigen, vorhersehbaren POST-API-Endpoint nutzen. Ein böswilliger Akteur könnte ein verstecktes JavaScript-Skript in eine bösartige Website einbetten, das eine präparierte Mutation an den GraphQL-API-Endpoint sendet. Besucht ein authentifizierter Nutzer die Angreiferseite, fügt sein Browser automatisch Session-Cookies hinzu und sendet einen Request an das GraphQL-Backend, als käme er vom legitimen Nutzer.

Allgemeine API-Sicherheitsmängel

Allein die Tatsache, dass GraphQL-Backends API-Backends sind, bedeutet: Sie unterliegen allen gängigen API-Sicherheitsrisiken. Dazu zählen die Umgehung der Autorisierung, gebrochene Authentifizierung, gebrochene Autorisierung auf Objektebene, uneingeschränkter Zugriff auf sensible Geschäftsabläufe, server-side request forgery (SSRF), allgemeine Sicherheits-Fehlkonfigurationen sowie cross-site scripting (XSS).

Best Practices für GraphQL-Sicherheit

Nach der Betrachtung der Bedrohungen folgen nun umsetzbare Best Practices für API-Sicherheit speziell für GraphQL-Backends:

SicherheitsproblemKategorie des SicherheitsproblemsBest Practice
Offenlegung sensibler Felder, IDOR, gebrochene Autorisierung auf ObjektebeneAutorisierungsproblemeZugriffskontrolle auf Feldebene
Unbefugter Zugriff, privilege escalationAutorisierungsproblemeKontextbezogene Zugriffskontrolle
Unbefugte Ausführung von Mutations per CSRFCSRF bei Mutation-OperationenNur „preflighted“ Requests akzeptieren und CSRF-Token, SameSite-Cookies sowie Origin-/Referer-Prüfungen erzwingen
SQL-Injection, Command-Injection, prompt injectionGraphQL-Injection-AngriffeParametrisierte Abfragen bzw. ORMs verwenden
Ressourcenerschöpfung durch verschachtelte oder komplexe AbfragenDenial-of-Service-BedrohungenGrenzen für Abfragetiefe und -komplexität
Beliebige Abfragen und DatenüberexpositionAbfragekontrolle und DatenexpositionPersisted Queries bzw. Allow-Lists (APQ)
Teure Abfragen, die den Server überlastenDenial-of-Service-BedrohungenTimeout- und Ressourcengrenzen
Serverüberlastung durch Missbrauch des einzelnen EndpointsDenial-of-Service-BedrohungenKostenbasiertes Rate-Limiting und Caching
Schema-Offenlegung und gezielte AngriffeOver-Fetching / InformationslecksIntrospection in der Produktion einschränken oder deaktivieren
Versehentliche Schwachstellen und unsicheres SchemaOver-Fetching / allgemeine API-SicherheitsmängelVersionskontrolle und Schema-Dokumentation
Gebrochene Authentifizierung, Umgehung der Autorisierung, XSS, SSRF, Fehlkonfigurationen, Offenlegung von Stack-Traces usw.Allgemeine API-Sicherheitsmängel, Informationslecks durch FehlerbehandlungRichtlinien von Apollo, OWASP und GraphQL.org befolgen

Frameworks für Autorisierung und Zugriffskontrolle

  • Zugriffskontrolle auf Feldebene: Damit Nutzer nur auf erlaubte Felder zugreifen oder sie ändern können, muss die GraphQL-Autorisierung auf einer Zugriffskontrolle auf Feldebene aufbauen. Tools wie graphql-shield helfen dabei, diese Regeln über alle Resolver hinweg anzuwenden. Beispiel:

const { rule, shield } = require('graphql-shield');

// define a rule to check if the user is an admin
const isAdmin = rule()((parent, args, ctx) => ctx.user.role === 'admin');

// apply the rule to specific fields
const permissions = shield({
  Query: {
    secretData: isAdmin,
  },
});
  • Kontextbezogene Zugriffskontrollen: Um unbefugten Zugriff zu verhindern, sollten Nutzerrollen, Request-Verhalten und weitere Kontextinformationen berücksichtigt werden. Praxistipp: OWASP-Tools wie der InQL Scanner helfen, Autorisierungslücken und kontextbezogene Zugriffskontrollen zu prüfen;

  • CSRF-Schutz: GraphQL-Backends brauchen CSRF-Schutz, um unbefugte Abfragen und Mutations zu stoppen. Server sollten die Ausführung jeder Operation verweigern, die aus einem Browser stammt, der den Request nicht „preflighted“ hat.

Abfrageanalyse und Ausführungsgrenzen

Zur Kontrolle der Abfragekomplexität und zur Abwehr von DoS gilt:

import express from 'express';
import { createHandler } from 'graphql-http';
import depthLimit from 'graphql-depth-limit';
import { schema } from './schema.js'; // import your GraphQL schema

const app = express();

// register GraphQL middleware for a maximum query depth of 5
app.use(
  '/api/graphql',
  createHandler({
    schema,
    validationRules: [depthLimit(5)],
  })
);
POST /api/graphql
{
  "id": "a1b2c3d4",   // hash of the whitelisted query
  "variables": { ... }
}

GraphQL-Rate-Limiting

Schon ein einziger Request kann einen Server überlasten, daher reicht klassisches Rate-Limiting nach IP-Adresse oder Nutzersitzung bei GraphQL nicht aus. Ein produktionsreifes GraphQL-Rate-Limiting verfolgt stattdessen einen feiner abgestuften Ansatz auf Basis einer Query-Cost-Analyse.

Diese Methode weist jedem Feld Kosten zu und steuert so, wie viel „Komplexität“ ein Nutzer pro Sitzung verbrauchen darf. Caching senkt die Serverlast zusätzlich und ermöglicht insgesamt höhere Rate-Limits, ohne die Leistung zu beeinträchtigen.

Schema-Sicherheit

Apollo empfiehlt, die GraphQL-Introspection in der Produktion immer zu deaktivieren, damit Angreifer das Schema nicht als Landkarte für ihre Erkundung nutzen können.

Noch ein wichtiger Tipp: GraphQL-Schemas gehören zu einem grundlegenden Bestandteil der AppSec-Verfahren. Sie sollten mit Versionskontrolle verwaltet, gut dokumentiert und regelmäßig überprüft werden.

Allgemeine Härtung für die Produktion

Weitere Best Practices für GraphQL-API-Sicherheit liefern diese Ressourcen:

GraphQL-APIs auf Sicherheitslücken testen und überwachen

Für starke GraphQL-Sicherheit empfiehlt sich ein mehrschichtiger Ansatz über den gesamten API-Lebenszyklus. Die folgenden Leitlinien helfen dabei:

  • Vor der Entwicklung: Schemas lassen sich früh mit Tools wie GraphQL-Inspector und eslint-plugin-graphql validieren. Zudem sollte das principle of least privilege (PoLP) durch den Entwurf von Zugriffskontrollen auf Feldebene durchgesetzt werden.

  • Während der Entwicklung: Linter wie GraphQL-ESLint lassen sich in die IDE integrieren. Lösungen für software composition analysis (SCA) identifizieren verwundbare dependencies, und static application security testing (SAST) deckt unsichere Resolver-Logik auf.

  • Vor dem Deployment: GraphQL-taugliche dynamic application security testing (DAST)-Tools finden Probleme zur Laufzeit. Auch interactive application security testing (IAST)-Software deckt Schwachstellen zur Laufzeit auf.

  • Nach dem Deployment: Empfehlenswert ist eine Plattform, die API-Discovery, GraphQL-fähiges Runtime-Monitoring und Cloud-Posture (etwa CSPM) vereint, um Fehlkonfigurationen in GraphQL-Servern und umliegenden Cloud-Diensten zu erkennen. Ergänzend erfassen Application-Performance-Monitoring (APM) und Observability-Systeme Leistung und Nutzung. Regelmäßige GraphQL-Pentests simulieren reale Angriffe und prüfen, wie die Abwehrmaßnahmen reagieren. Produktions-Endpoints lassen sich zudem fortlaufend mit sicheren, GraphQL-fähigen dynamischen Scans validieren, um Drift (etwa neu offengelegte Felder oder unbegrenzte Komplexität) und Regressionen zu erkennen.

Wie Wiz GraphQL-APIs absichert

Wie gezeigt, kann die Architektur von GraphQL zu besonderen Angriffsvektoren führen: Ein einziger fehlkonfigurierter Resolver oder ein schlecht abgesicherter GraphQL-Endpoint kann die gesamte Infrastruktur ernsten Bedrohungen aussetzen.

Speziell für GraphQL hilft Wiz API Security Posture Management (API SPM) Teams dabei, die API-Sicherheitslage fortlaufend zu verfolgen, zu prüfen, welche Endpoints tatsächlich exponiert sind, und Schwächen in Schema oder Resolver mit den Identitäten, Datastores und Cloud-Ressourcen zu verknüpfen, die diese APIs erreichen können. Dieser zusätzliche Kontext zählt besonders, wenn ein GraphQL-Endpoint KI-Funktionen oder Inferenz-Workflows bereitstellt, denn ein exponierter Resolver kann auch den Modellzugriff oder sensible Trainings- und Inferenzdaten offenlegen.

Die zentrale Erkenntnis: Um GraphQL-Backends zu schützen, braucht es eine einheitliche Lösung wie Wiz.

Wiz Cloud verfolgt bei der GraphQL-API-Sicherheit einen mehrschichtigen Ansatz:

  • Discovery: Wiz API SPM nutzt runtime sensors, API-Gateways, Management-Tools und API-Spezifikationen, um GraphQL-Endpoints automatisch zu erkennen. So lässt sich ein vollständiges, fortlaufend aktualisiertes Inventar der APIs pflegen – einschließlich GraphQL-Endpoints, die ungewollt öffentlich exponiert wurden;

  • Risikobewertung: Mit API SPM und dem Wiz Dynamic Scanner untersucht Wiz die GraphQL-Endpoints, um Fehlkonfigurationen, unsichere Schemas, Autorisierungslücken und weitere API-Schwächen aufzudecken, darunter Probleme aus den OWASP API Top 10. Wiz validiert außerdem die öffentliche Exposition und mögliche attack paths, damit sich reale Risiken einordnen und priorisieren lassen;

  • Aufdecken toxischer Kombinationen: Wiz geht über oberflächliches Scannen hinaus. Durch die Kontextualisierung von API-Risiken zusammen mit Merkmalen wie der Offenlegung sensibler Daten, Autorisierungsabläufen und Hosting-Ressourcen erkennt Wiz Ketten von Problemen, die Angreifer ausnutzen könnten, um die GraphQL-Infrastruktur zu kompromittieren.

Kurz gesagt: Auf Wiz ist Verlass für:

  • ein umfassendes Inventar der API-Endpoints;

  • Erkennung und Alarmierung bei externer Exposition;

  • Analyse und Validierung von GraphQL-Schemas;

  • Erkennung und Scannen sensibler Daten;

  • Scannen von Authorization-Headern;

  • Erkennung von Autorisierungs-Fehlkonfigurationen;

  • Metriken zu API-Leistung und -Sicherheit;

  • Mapping der Hosting-Ressourcen;

  • ein einheitliches Dashboard für API-Sicherheit.

So sieht es in der Praxis aus: Demo vereinbaren, um GraphQL-Endpoints automatisch zu erkennen, ihren code-to-cloud-Kontext sichtbar zu machen und die Fixes zu priorisieren, die wirklich zählen.