Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
API Security Testing: Praxis-Guide für REST und GraphQL APIs - Illustration einer Sicherheitsanalyse mit Netzwerk-Scans und Schwachstellensuche
Offensive Security

API Security Testing: Praxis-Guide für REST und GraphQL APIs

API Security Testing deckt Schwachstellen auf die klassische Web-Tests übersehen: IDOR in API-Endpunkten, fehlerhafte Zugriffskontrollen, Mass Assignment, BOLA/BFLA, GraphQL-Introspection, JWT-Schwachstellen und Rate-Limiting-Bypass. Dieser Guide erklärt Testmethodik, Tools (Burp Suite, OWASP ZAP, Postman, GraphQL-Voyager) und OWASP API Security Top 10 2023.

Vincent Heinen Vincent Heinen Abteilungsleiter Offensive Services
11 Min. Lesezeit
OSCP+ OSCP OSWP OSWA

TL;DR

APIs waren laut Gartner 2024 der häufigste Angriffsvektor für Web-Applikationen - klassische Web-Tests erfassen die zugehörigen Schwachstellen jedoch systematisch nicht. Dieser Guide beschreibt die Testmethodik gegen die OWASP API Security Top 10 (2023): Von BOLA (Broken Object Level Authorization), bei dem Angreifer durch simple ID-Manipulation auf fremde Objekte zugreifen, über Mass Assignment bis zu BFLA, wo normale Nutzer Admin-Endpunkte aufrufen. Burp Suite mit der Autorize-Extension automatisiert BOLA-Tests, GraphQL-Voyager visualisiert Schema-Strukturen für Introspection-Angriffe. Pflichtlektüre für jeden, der REST- oder GraphQL-APIs absichern muss.

Diese Zusammenfassung wurde KI-gestützt erstellt (EU AI Act Art. 52).

Inhaltsverzeichnis (9 Abschnitte)

APIs sind das unsichtbare Rückgrat moderner Applikationen - und eine der häufigsten Angriffsquellen. Laut Gartner waren APIs 2024 der häufigste Angriffsvektor für Web-Applikationen. API Security Testing erfordert andere Methoden als klassisches Web-Testing: APIs haben keine sichtbare UI, ermöglichen direkte Daten-Zugriffe und leiden unter API-spezifischen Schwachstellen wie BOLA (Broken Object Level Authorization) und Mass Assignment.

OWASP API Security Top 10 (2023)

OWASP API Security Top 10:

  API1:  Broken Object Level Authorization (BOLA)
         → Angreifer manipuliert IDs um fremde Objekte zuzugreifen

  API2:  Broken Authentication
         → Schwache Tokens, kein Rate-Limiting auf Login

  API3:  Broken Object Property Level Authorization
         → Mass Assignment, Daten-Exposition in Responses

  API4:  Unrestricted Resource Consumption
         → Kein Rate-Limiting → DoS, Account Enumeration

  API5:  Broken Function Level Authorization (BFLA)
         → Normaler User kann Admin-Endpunkte aufrufen

  API6:  Unrestricted Access to Sensitive Business Flows
         → Logik-Fehler in Workflows (Bulk-Kauf, Wiederverwendung)

  API7:  Server Side Request Forgery (SSRF)
         → API ruft interne Ressourcen auf Angreifer-Anweisung auf

  API8:  Security Misconfiguration
         → Debug-Endpunkte, CORS-Fehlkonfiguration, verbose Errors

  API9:  Improper Inventory Management
         → Shadow-APIs, undokumentierte v1-Endpunkte vergessen

  API10: Unsafe Consumption of APIs
         → API vertraut Antworten von Drittanbieter-APIs blind

Reconnaissance: API-Endpunkte entdecken

Phase 1 - API Discovery:

OpenAPI/Swagger-Dokumentation finden:
  /swagger-ui.html
  /api-docs
  /swagger.json
  /openapi.json
  /v2/api-docs
  /api/v1/swagger
  /docs

  # Mit ffuf automatisiert:
  ffuf -w /usr/share/wordlists/api-paths.txt \
    -u https://api.example.com/FUZZ \
    -mc 200,201,301,302 \
    -o api-endpoints.json

JavaScript-Dateien nach API-Calls durchsuchen:
  # Tool: LinkFinder oder Postman Interceptor
  python3 linkfinder.py -i https://app.example.com -d -o cli

Burp Suite: API-Endpunkte aus Browser-Traffic extrahieren:
  → Burp Target → Site Map → Filtern nach API-Pfaden
  → Burp Extensions: "API Scanner", "InQL" (GraphQL)

API-Versionierung prüfen:
  /api/v1/users  → funktioniert?
  /api/v2/users  → neue Version?
  /api/v3/users  → Beta?
  /api/users     → Version-less (manchmal weniger geschützt!)
  /v1/users      → prefix-loser Pfad

Mobile-App APK analysieren:
  # apktool: Decompilieren
  apktool d meine-app.apk
  # Alle URLs/Endpoints extrahieren:
  grep -r "https://api" meine-app/
  grep -rE "\"\/[a-z]+\/[a-z]+" meine-app/

API1: Broken Object Level Authorization (BOLA)

BOLA - Häufigste und kritischste API-Schwachstelle:

Beispiel: GET /api/v1/orders/{orderId}

  Normaler Nutzer (user-123):
  GET /api/v1/orders/1001   → Eigene Bestellung → OK
  GET /api/v1/orders/1002   → FREMDE Bestellung → sollte 403 geben!
                              Wenn 200: BOLA-Schwachstelle!

Testmethodik:
  1. Als User A anmelden, eigene Ressourcen-ID notieren
  2. Als User B anmelden, mit User-A-IDs auf Ressourcen zugreifen
  3. Auch: als nicht-authentifizierter User testen

  Burp Suite - BOLA-Test:
  # Zwei Burp-Instanzen (oder Cookie-Jar-Trick):
  # Session 1: User A Token
  # Session 2: User B Token
  # Request von Session 1 → repeaten → Session 2's Cookie einsetzen

  Varianten:
  Direkte ID: /api/users/123 → /api/users/124 (sequential!)
  UUID:        /api/docs/550e8400-e29b-41d4-a716 → andere UUID
  Encoded:     /api/files/dXNlcjEyMw== → Base64-decode, andere ID encoden

Automatisiert mit Autorize (Burp Extension):
  1. Autorize Extension installieren
  2. User-B-Cookie in "Interception filter" eintragen
  3. Als User-A browsen
  4. Autorize replayed alle Requests mit User-B-Cookie
  5. Tabellarische Ausgabe: "Same response" = BOLA!

BOLA-Schutz im Code:
  # Schlecht (nur ID prüfen):
  order = Order.find(params[:order_id])
  return order

  # Gut (scoped zu aktuellem User):
  order = current_user.orders.find(params[:order_id])
  # → 404 wenn Bestellung nicht dem User gehört!

API5: Broken Function Level Authorization (BFLA)

BFLA - Admin-Funktionen für normale User erreichbar:

Beispiel:
  GET  /api/v1/users        → User-Liste (sollte nur Admin!)
  POST /api/v1/users/delete → User löschen (sollte nur Admin!)
  GET  /api/v1/admin/stats  → Statistiken

  Normale User probieren Admin-Endpunkte:
  → Viele APIs prüfen nur AuthN (eingeloggt?) nicht AuthZ (Berechtigungen?)!

Testmethodik:
  1. API-Dokumentation auf Admin-Endpunkte scannen
  2. Alle Endpunkte mit normalem User-Token aufrufen
  3. HTTP-Verb-Fuzzing: GET vs POST vs PUT vs DELETE vs PATCH

  HTTP-Verb-Fuzzing:
  # Normaler GET erlaubt, aber was mit DELETE?
  curl -X DELETE -H "Authorization: Bearer USER_TOKEN" \
    https://api.example.com/api/v1/users/999

  # "Method not allowed" vs "403" vs "200" → Unterschied wichtig!
  # 405: Methode nicht erlaubt
  # 403: Methode erlaubt, aber nicht für diesen User
  # 200: BFLA! User kann adminstrativen Endpunkt aufrufen!

Masscan nach Endpunkten mit ffuf (Verb-Fuzzing):
  ffuf -w verbs.txt \
    -X FUZZ \
    -H "Authorization: Bearer USER_TOKEN" \
    -u https://api.example.com/api/v1/users \
    -mc 200,201,204 \
    -v

Mass Assignment und Excessive Data Exposure

API3: Mass Assignment:

Backend nimmt alle Parameter eines PUT/PATCH-Requests entgegen:

  PATCH /api/v1/users/me
  {
    "name": "Max Mustermann",
    "email": "max@example.com",
    "role": "admin"       ← Sollte ignoriert werden!
  }

  Wenn Server role-Parameter akzeptiert:
  → Benutzer kann sich selbst zum Admin hochstufen!

  Weitere Targets:
  "isVerified": true    (E-Mail-Verifikation überspringen)
  "balance": 9999       (Kontostand manipulieren)
  "subscription": "pro" (Abo upgraden)

Test:
  # Alle Felder des Objekts aus GET-Response extrahieren
  curl -s https://api.example.com/api/v1/users/me \
    -H "Authorization: Bearer TOKEN" | jq 'keys'
  # Alle Keys in PATCH-Request einfügen mit geänderten Werten

Excessive Data Exposure:
  # API gibt mehr Daten zurück als die UI anzeigt:
  GET /api/v1/users/me
  {
    "name": "Max",
    "email": "max@example.com",
    "role": "user",
    "passwordHash": "$2b$12$...",  ← Nicht für Client gedacht!
    "internalNotes": "VIP-Kunde",   ← Intern!
    "ssn": "123-45-6789"            ← PII!
  }
  → Client filtert UI-seitig → API gibt trotzdem alle Felder zurück
  → Direkte API-Aufrufe → Datenleck!

JWT-Schwachstellen

JWT (JSON Web Token) Schwachstellen:

Grundstruktur: header.payload.signature (Base64URL-kodiert)

Häufige Schwachstellen:

1. Algorithm None:
   # Header ändern:
   {"alg": "none", "typ": "JWT"}
   # Signatur weglassen: header.payload.
   # Wenn Server "none" akzeptiert → jede Payload gültig!

2. RS256 → HS256 downgrade:
   # Server signiert mit RS256 (asymmetrisch)
   # Angreifer: Header auf HS256 ändern
   # HS256-Signatur mit dem ÖFFENTLICHEN Schlüssel erstellen
   # (Server verifiziert HS256 mit öffentlichem Schlüssel = HMAC-Key)

3. Schwacher Secret-Key (HS256):
   # Offline-Bruteforce:
   hashcat -a 0 -m 16500 jwt.token /usr/share/wordlists/rockyou.txt
   # jwt_tool:
   python3 jwt_tool.py TOKEN -C -d wordlist.txt

4. kid-Header-Injection:
   # "kid" (Key ID) zeigt welchen Schlüssel der Server nutzen soll
   {"alg":"HS256","kid":"../../dev/null"}
   # Server liest Schlüssel aus /dev/null (leere Datei) → signiert mit leerem Key!

JWT-Testing mit jwt_tool:
  # Installation:
  pip install jwt_tool

  # Token testen:
  python3 jwt_tool.py TOKEN

  # Algorithm None:
  python3 jwt_tool.py TOKEN -X a

  # Key-Bruteforce:
  python3 jwt_tool.py TOKEN -C -d wordlist.txt

  # Payload manipulieren:
  python3 jwt_tool.py TOKEN -T  # Interaktiver Modus

GraphQL Security Testing

GraphQL-spezifische Schwachstellen:

Introspection (häufig enabled in Produktion!):
  # Alle Typen abfragen:
  {
    __schema {
      types { name kind description }
    }
  }

  # Alle Queries und Mutations:
  {
    __schema {
      queryType { fields { name args { name type { name kind } } } }
      mutationType { fields { name args { name } } }
    }
  }

  # Tool: GraphQL Voyager (visuelle Schema-Exploration)
  # Tool: InQL (Burp Suite Extension für GraphQL)

Batching-Angriffe (Brute Force):
  # Statt 1000 separate Requests → 1 Batch-Request:
  [
    {"query": "mutation { login(email: \"admin@a.de\", password: \"pass1\") }"},
    {"query": "mutation { login(email: \"admin@a.de\", password: \"pass2\") }"},
    ...999x...
  ]
  # Rate-Limiting auf Requests-Ebene → umgangen!
  # Schutz: Rate-Limiting auf Operationen-Ebene, nicht Request-Ebene

Field-Level BOLA:
  # User kann eigenes Profil abfragen:
  { user(id: "me") { name email } }
  # Kann er andere User abfragen?
  { user(id: "other-user-id") { name email password } }

Deeply Nested Queries (DoS):
  { user { posts { author { posts { author { posts { ... } } } } } } }
  # Exponentiell wachsende DB-Abfragen → DoS!
  # Schutz: Query-Depth-Limiting, Query-Cost-Analysis

GraphQL-Testing mit Clairvoyance:
  # Schema ohne Introspection rekonstruieren:
  python3 clairvoyance.py -o schema.json https://api.example.com/graphql

Rate-Limiting-Tests

API4: Unrestricted Resource Consumption - Rate-Limiting testen:

Szenarien:
  1. Login-Endpoint: Brute-Force-Schutz vorhanden?
  2. OTP/2FA: 6-stellige OTP → 1.000.000 Versuche mit Rate-Limit blockiert?
  3. Password Reset: Tokens generierbar ohne Limit?
  4. Daten-Abfragen: Export-API → beliebig viele Exports?

Testing mit Burp Intruder:
  POST /api/v1/login
  {
    "email": "admin@example.com",
    "password": "§PASSWORT§"
  }
  → Intruder → Pitchfork oder Sniper
  → Wordlist mit Passwörtern
  → 429 Too Many Requests nach X Versuchen? → Rate-Limit vorhanden

Testing mit ffuf:
  seq 1 1000 | while read i; do
    curl -s -o /dev/null -w "%{http_code}\n" \
      -X POST https://api.example.com/api/v1/auth/send-otp \
      -H "Content-Type: application/json" \
      -d '{"phone": "+4917612345678"}'
  done | sort | uniq -c
  # 429 erscheint? → wann?

Rate-Limit-Bypass-Techniken:
  → X-Forwarded-For: 1.2.3.4 (IP-Spoofing bei schlechter Implementierung)
  → X-Real-IP: 10.0.0.1
  → User-Agent rotieren
  → IPv6-Adressen rotieren (wenn v6 nicht rate-limited)
  → Langsame Rate (1 Request/5 Minuten → oft kein Alert)

API Security Testbericht

Dokumentation der Findings:

Standard-Finding-Template für API-Tests:

  Title: Broken Object Level Authorization in /api/v1/orders/{id}
  OWASP: API1:2023 - BOLA
  CVSS:  7.5 (High) - AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
  Affected: GET /api/v1/orders/{orderId}

  Beschreibung:
  Authentifizierte Benutzer können Bestellungen anderer Nutzer
  durch Manipulation der orderId-Parameter abfragen. Die API
  prüft nur ob der Nutzer authentifiziert ist, nicht ob die
  Bestellung dem Nutzer gehört.

  PoC (Proof of Concept):
  # Bestellung von User A:
  curl -H "Authorization: Bearer USER_A_TOKEN" \
    https://api.example.com/api/v1/orders/10001
  # {"id": 10001, "user_id": 1, "amount": 299.99, ...}

  # User B greift auf User A's Bestellung zu:
  curl -H "Authorization: Bearer USER_B_TOKEN" \
    https://api.example.com/api/v1/orders/10001
  # {"id": 10001, "user_id": 1, "amount": 299.99, ...}
  # → 200 OK statt 403 Forbidden!

  Impact:
  Angreifer kann alle Bestellungen aller Nutzer abfragen,
  inklusive Name, Adresse und Zahlungsdaten.

  Remediation:
  Alle Datenbankabfragen müssen mit dem authentifizierten
  Nutzer scopen:
    order = current_user.orders.find_by!(id: params[:id])
  Rückgabe von 404 statt 403 empfohlen (Information Disclosure vermeiden)

Tools für den Pentest-Bericht:
  → Swagger/OpenAPI-Diff: Änderungen zwischen API-Versionen
  → nuclei: Templates für bekannte API-Schwachstellen
  → Postman: API-Collections für Reproduzierbarkeit dokumentieren

Nächster Schritt

Unsere zertifizierten Sicherheitsexperten beraten Sie zu den Themen aus diesem Artikel — unverbindlich und kostenlos.

Kostenlos · 30 Minuten · Unverbindlich

Artikel teilen

Über den Autor

Vincent Heinen
Vincent Heinen

Abteilungsleiter Offensive Services

M.Sc. IT-Sicherheit mit über 5 Jahren Erfahrung in offensiver Sicherheitsanalyse. Leitet die Durchführung von Penetrationstests mit Spezialisierung auf Web-Applikationen, Netzwerk-Infrastruktur, Reverse Engineering und Hardware-Sicherheit. Verantwortlich für mehrere Responsible Disclosures.

OSCP+ OSCP OSWP OSWA
Zertifiziert ISO 27001ISO 9001AZAVBSI

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung