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:
| Sicherheitsproblem | Kategorie des Sicherheitsproblems | Best Practice |
|---|---|---|
| Offenlegung sensibler Felder, IDOR, gebrochene Autorisierung auf Objektebene | Autorisierungsprobleme | Zugriffskontrolle auf Feldebene |
| Unbefugter Zugriff, privilege escalation | Autorisierungsprobleme | Kontextbezogene Zugriffskontrolle |
| Unbefugte Ausführung von Mutations per CSRF | CSRF bei Mutation-Operationen | Nur „preflighted“ Requests akzeptieren und CSRF-Token, SameSite-Cookies sowie Origin-/Referer-Prüfungen erzwingen |
| SQL-Injection, Command-Injection, prompt injection | GraphQL-Injection-Angriffe | Parametrisierte Abfragen bzw. ORMs verwenden |
| Ressourcenerschöpfung durch verschachtelte oder komplexe Abfragen | Denial-of-Service-Bedrohungen | Grenzen für Abfragetiefe und -komplexität |
| Beliebige Abfragen und Datenüberexposition | Abfragekontrolle und Datenexposition | Persisted Queries bzw. Allow-Lists (APQ) |
| Teure Abfragen, die den Server überlasten | Denial-of-Service-Bedrohungen | Timeout- und Ressourcengrenzen |
| Serverüberlastung durch Missbrauch des einzelnen Endpoints | Denial-of-Service-Bedrohungen | Kostenbasiertes Rate-Limiting und Caching |
| Schema-Offenlegung und gezielte Angriffe | Over-Fetching / Informationslecks | Introspection in der Produktion einschränken oder deaktivieren |
| Versehentliche Schwachstellen und unsicheres Schema | Over-Fetching / allgemeine API-Sicherheitsmängel | Versionskontrolle und Schema-Dokumentation |
| Gebrochene Authentifizierung, Umgehung der Autorisierung, XSS, SSRF, Fehlkonfigurationen, Offenlegung von Stack-Traces usw. | Allgemeine API-Sicherheitsmängel, Informationslecks durch Fehlerbehandlung | Richtlinien 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:
Nutzereingaben und alle eingehenden Abfragedaten bereinigen, um GraphQL-Sicherheitsprobleme im Body zu erkennen. Anschließend lassen sich mit Tools wie graphql-depth-limit Grenzen für die Abfragetiefe setzen, um ressourcenintensive Requests zu blockieren. Beispiel:
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)],
})
);Für maximale Sicherheit empfiehlt es sich, Persisted Queries zu nutzen oder per Whitelisting nur bestimmte Abfragen zuzulassen. So lassen sich völlig beliebige Abfragen von Angreifern verhindern. Beispiel:
POST /api/graphql
{
"id": "a1b2c3d4", // hash of the whitelisted query
"variables": { ... }
}Für einzelne Operationen Timeout-Kontrollen und Ressourcengrenzen anwenden. So werden legitime, aber teure Abfragen beendet, bevor sie den Server überlasten, und DoS-Bedrohungen abgewehrt.
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.