CertifiedHacker

API Security: REST, GraphQL en gRPC

Uitgebreid hoofdstuk over het testen van API's: REST endpoints, GraphQL introspection, gRPC reflection, OWASP API Top 10, BOLA/IDOR, Mass Assignment en praktische workflow.

API Security: REST, GraphQL en gRPC

De bouwstenen van het moderne web

Er was een tijd — en het voelt als gisteren, maar het is inmiddels meer dan tien jaar geleden, wat in de webontwikkeling neerkomt op het Jurrassic Park tijdperk minus de dinosaurussen maar mét dezelfde hoeveelheid chaos — dat een webapplicatie een monoliet was. Één groot PHP-bestand dat HTML genereerde, data uit de database haalde, formulieren verwerkte, en als je geluk had ook nog de juiste pagina teruggaf. De server deed alles. De browser was een passieve ontvanger, een stomme terminal die HTML kreeg opgediend alsof het een bord stamppot was bij een bedrijfskantine: je at wat je kreeg, en je klaagde niet.

Die tijd is voorbij. Het moderne web is een architectuur van losse onderdelen die met elkaar praten via API’s — Application Programming Interfaces. De frontend is een Single Page Application in React, Vue of Angular die draait in de browser van de gebruiker. De backend is een verzameling microservices die data leveren in JSON-formaat. Daartussenin zitten API gateways, load balancers, CDN’s, en een hoeveelheid middleware die je doet afvragen of iemand ooit het woord “eenvoud” heeft gehoord.

En dát is waar het interessant wordt voor ons. Want als de frontend en de backend gescheiden zijn, dan is de API het scharnierpunt. De API verwerkt de data. De API handhaaft de authenticatie. De API bevat de bedrijfslogica die je wilt testen. De frontend is het decor; de API is het toneel. En als pentester sta je achter het gordijn, met een Burp Suite proxy als verrekijker, en je kijkt naar alles wat het publiek niet mag zien.

Dit hoofdstuk gaat over het testen van API’s. Niet het soort testen waarbij je een paar endpoints bezoekt en kijkt of je een 200 terugkrijgt — dat is monitoring, geen pentesting. Nee, we gaan kijken naar autorisatie die faalt zodra je een ID wijzigt, naar authenticatie die vertrouwt op tokens die je kunt vervalsen, naar GraphQL-query’s die het hele datamodel onthullen, en naar gRPC-services die ervan uitgaan dat alleen de cliënt-applicatie ze aanroept.


REST: de taal van het web

Wat REST is (en niet is)

REST — Representational State Transfer — is geen protocol. Het is geen standaard. Het is een architectuurstijl, bedacht door Roy Fielding in zijn proefschrift uit 2000, en vervolgens door de rest van de wereld geïnterpreteerd met de nauwkeurigheid waarmee een kind een tekening van Picasso na-aapt. Fielding beschreef een elegant stelsel van constraints: stateless communicatie, uniforme interfaces, een geïdentificeerd resource-model. Wat de industrie ervan maakte was “stuur JSON over HTTP en noem het REST.”

En eerlijk gezegd werkt dat verbazend goed. De meeste API’s die je tegenkomt volgen een herkenbaar patroon:

GET    /api/v1/users          # Lijst van gebruikers
GET    /api/v1/users/42        # Specifieke gebruiker
POST   /api/v1/users           # Nieuwe gebruiker aanmaken
PUT    /api/v1/users/42        # Gebruiker bijwerken
DELETE /api/v1/users/42        # Gebruiker verwijderen

Dat is de theorie. De praktijk is interessanter. In de praktijk heb je API’s die DELETE-requests versturen via POST met een _method=DELETE parameter omdat iemand ooit hoorde dat sommige proxies DELETE niet doorlaten. Je hebt API’s die paginering implementeren via een Link header, en API’s die het doen via ?page=2&per_page=50, en API’s die het helemaal niet doen waardoor je 47.000 records in één response terugkrijgt en je laptop even stilstaat om na te denken over zijn leveneskeuzes.

API verkenning

Voordat je kunt testen, moet je weten wat er te testen valt. En dat is bij API’s tegelijkertijd makkelijker en moeilijker dan bij gewone webapplicaties. Makkelijker, omdat veel API’s zichzelf documenteren. Moeilijker, omdat de endpoints die niet gedocumenteerd zijn vaak de meest interessante zijn.

OpenAPI / Swagger documentatie

De eerste stap is altijd: kijk of er een OpenAPI (voorheen Swagger) specificatie beschikbaar is. Dit is een JSON- of YAML-bestand dat elk endpoint, elke parameter, elk request- en responsmodel beschrijft. Het is alsof de verdediging je een plattegrond van het kasteel geeft met een vriendelijk briefje erbij: “Hier, veel plezier.”

# Standaard locaties voor OpenAPI specs
curl -s https://target.com/swagger.json | head -20
curl -s https://target.com/api/swagger.json
curl -s https://target.com/api-docs
curl -s https://target.com/v1/api-docs
curl -s https://target.com/.well-known/openapi.json
curl -s https://target.com/openapi.yaml

# Swagger UI (interactieve documentatie)
# Browser: https://target.com/swagger-ui/
# Browser: https://target.com/api/docs

Als je een Swagger-spec vindt, heb je goud in handen. Je kent nu elk endpoint, welke HTTP-methoden het accepteert, welke parameters het verwacht, en welke response-codes het kan teruggeven. Import het in Postman of Burp Suite en je hebt een complete testharness.

Endpoint discovery zonder documentatie

Maar wat als er géén documentatie is? Dan ga je op zoek. En die zoektocht begint op drie plekken: de JavaScript-broncode, het netwerkverkeer, en wordlist-based fuzzing.

# Stap 1: JavaScript analyseren
# Download alle JS-bestanden en zoek naar API-paden
curl -s https://target.com/ | grep -oP 'src="[^"]*\.js"' | while read src; do
  url=$(echo $src | grep -oP '"[^"]*"' | tr -d '"')
  curl -s "https://target.com$url" | grep -oP '["'"'"'](/api/[^"'"'"']*)['"'"'"]'
done

# Stap 2: Burp Suite passief scannen
# Zet Burp als proxy, gebruik de applicatie normaal,
# en bekijk daarna de sitemap voor alle API-calls

# Stap 3: Endpoint fuzzing
ffuf -u https://target.com/api/v1/FUZZ -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt -mc 200,201,204,301,302,401,403
ffuf -u https://target.com/api/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc all -fc 404

# Stap 4: API versie-enumeratie
# Als /api/v2/ bestaat, bestaat /api/v1/ misschien ook nog
for v in v1 v2 v3 v4 beta internal admin; do
  code=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com/api/$v/")
  echo "$v: $code"
done

Die laatste techniek — het checken van oude API-versies — is bijzonder waardevol. Ontwikkelaars upgraden hun API van v1 naar v2 en voegen daarbij betere autorisatiecontroles toe. Maar v1 staat nog online, zonder die controles. Het is alsof je de voordeur hebt versterkt met een nieuw slot, maar de achterdeur bent vergeten.


De OWASP API Security Top 10

De OWASP API Security Top 10 is de bijbel voor API-pentesting. Waar de reguliere OWASP Top 10 zich richt op webapplicaties in het algemeen, focust de API-versie specifiek op de kwetsbaarheden die ontstaan wanneer applicaties communiceren via API’s. De lijst werd voor het eerst gepubliceerd in 2019 en herzien in 2023, en als je hem naast je ervaringen legt, herken je elk item als iets dat je in het wild bent tegengekomen.

API1: Broken Object Level Authorization (BOLA)

Dit is de moeder aller API-kwetsbaarheden. Het is zo veelvoorkomend dat het op nummer één staat, en het is zo simpel dat je je afvraagt hoe het in 2026 nog steeds een probleem kan zijn. Het antwoord is: omdat het makkelijk is om het fout te doen en moeilijk om het goed te doen.

BOLA — ook bekend als IDOR (Insecure Direct Object Reference) — treedt op wanneer een API een object retourneert op basis van een identifier die de gebruiker aanlevert, zonder te controleren of die gebruiker dat object mag zien.

# Je eigen profiel
GET /api/v1/users/142 HTTP/1.1
Authorization: Bearer eyJhbG...
Host: target.com

# Response: 200 OK
{"id": 142, "name": "Jan", "email": "jan@example.nl", "ssn": "123456789"}

# Nu wijzig je het ID
GET /api/v1/users/143 HTTP/1.1
Authorization: Bearer eyJhbG...
Host: target.com

# Response: 200 OK  <-- BOLA! Je ziet iemand anders' data
{"id": 143, "name": "Piet", "email": "piet@example.nl", "ssn": "987654321"}

Het probleem is niet dat het endpoint bestaat. Het probleem is dat de server je token valideert (“ja, je bent ingelogd”) maar niet checkt of je user 143 mag opvragen (“nee, dat is niet jouw profiel”). De authenticatie werkt; de autorisatie niet.

In Burp Suite test je dit systematisch met Intruder:

# Burp Intruder setup:
# 1. Stuur het request naar Intruder (Ctrl+I)
# 2. Markeer het ID als payload positie: /api/v1/users/§142§
# 3. Payload type: Numbers, van 1 tot 500, stap 1
# 4. Vergelijk response-lengtes: als ze variëren, heb je data

# Automatiseren met curl:
for id in $(seq 1 200); do
  resp=$(curl -s -H "Authorization: Bearer $TOKEN" \
    "https://target.com/api/v1/users/$id")
  len=${#resp}
  echo "ID $id: $len bytes"
done | sort -t: -k2 -n

Let op: BOLA beperkt zich niet tot numerieke ID’s. UUID’s lijken veiliger, maar als je een UUID kunt raden of lekken (via een ander endpoint, een error message, of een predictable UUID v1), ben je er ook.

API2: Broken Authentication

API-authenticatie is een vak apart. Terwijl webapplicaties vaak sessie-cookies gebruiken die door de browser worden beheerd, gebruiken API’s tokens — Bearer tokens, API keys, JWT’s, OAuth tokens — die door de cliënt-applicatie worden beheerd. En die cliënt-applicatie is JavaScript in een browser, wat betekent dat elke gebruiker met DevTools het token kan inzien, kopiëren en manipuleren.

# Test 1: Ontbrekende authenticatie
# Probeer endpoints zonder Authorization header
curl -s https://target.com/api/v1/users
curl -s https://target.com/api/v1/admin/dashboard

# Test 2: Token hergebruik na logout
# Log in, kopieer het token, log uit, gebruik het token opnieuw
# Als het nog werkt: tokens worden niet geïnvalideerd bij logout

# Test 3: Voorspelbare tokens
# Verzamel meerdere tokens en vergelijk ze
# Incrementele nummers? Timestamp-based? Base64 van user_id?

# Test 4: Brute force
# Is er rate limiting op /api/login?
hydra -l admin@target.com -P /usr/share/wordlists/rockyou.txt \
  target.com https-post-form \
  "/api/v1/auth/login:email=^USER^&password=^PASS^:Invalid credentials"

API3: Broken Object Property Level Authorization

Dit is de subtielere variant van BOLA. De API geeft je wél het juiste object terug, maar stuurt te veel velden mee. Je vraagt om je eigen profiel en krijgt naast je naam en email ook je BSN, salarisgegevens, en de notitie die HR over je heeft geschreven (die je liever niet had gelezen).

// Request: GET /api/v1/me
// Response bevat meer dan de frontend toont:
{
  "id": 142,
  "name": "Jan",
  "email": "jan@example.nl",
  "role": "user",
  "internal_notes": "Klant betaalt altijd te laat",
  "password_hash": "$2b$12$LJ3...",
  "api_key": "sk_live_abc123...",
  "stripe_customer_id": "cus_xyz..."
}

De frontend filtert dit en toont alleen naam en email. Maar Burp Suite toont alles. Dit is een veelgemaakte architectuurfout: de backend stuurt het volledige databaseobject naar de frontend en vertrouwt erop dat de frontend de juiste velden selecteert. Dat is als een dokter die je complete medische dossier meestuurt met de uitslag van je bloedonderzoek, en hoopt dat je de pagina over je buurman niet leest.

Mass Assignment

De omgekeerde richting is minstens zo gevaarlijk. Mass Assignment treedt op wanneer de API meer velden accepteert dan bedoeld:

# Normaal profiel-update request (wat de frontend stuurt)
PUT /api/v1/users/142
{"name": "Jan de Vries"}

# Mass Assignment poging (wat een aanvaller stuurt)
PUT /api/v1/users/142
{"name": "Jan de Vries", "role": "admin", "is_verified": true, "credit_balance": 99999}

# Variaties om te proberen:
# - Voeg "role", "is_admin", "admin", "privilege" toe
# - Voeg "email_verified", "is_active", "status" toe
# - Voeg "price", "amount", "discount", "credit" toe
# - Voeg "password", "password_hash" toe
# - Kijk welke velden de API teruggeeft in GET en stuur ze mee in PUT/PATCH

Het ontdekken van mass-assignment-velden is een kwestie van observeren en proberen. Kijk naar de response van een GET-request: elk veld dat je ziet, is een kandidaat om mee te sturen in een PUT of PATCH. En kijk naar andere endpoints — als /api/admin/users/142 een role veld toont, dan is dat veld de moeite waard om te proberen in het reguliere /api/users/142 endpoint.

API4: Unrestricted Resource Consumption

API’s zonder rate limiting zijn als een buffer zonder limiet: iedereen kan zo vaak opscheppen als hij wil, tot het eten op is — of in dit geval, tot de server plat ligt of tot de aanvaller alle mogelijke wachtwoorden heeft geprobeerd.

# Test rate limiting: hoeveel requests per seconde kun je doen?
for i in $(seq 1 100); do
  code=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST https://target.com/api/v1/auth/login \
    -H "Content-Type: application/json" \
    -d '{"email":"test@test.com","password":"wrong'$i'"}')
  echo "Request $i: HTTP $code"
done

# Als je na 100 requests nog steeds 401 krijgt (en geen 429):
# Er is geen rate limiting. Brute force is mogelijk.

# Bypass technieken als er wél rate limiting is:
# 1. Wissel IP via X-Forwarded-For
curl -H "X-Forwarded-For: 1.2.3.$((RANDOM % 255))" ...
# 2. Wissel gebruikersnaam in rotatie
# 3. Vertraag naar net onder de limiet
# 4. Gebruik meerdere API keys/sessions tegelijk

API5: Broken Function Level Authorization

Als BOLA gaat over “ik kan objecten van anderen zien”, gaat API5 over “ik kan functies uitvoeren die niet voor mij bedoeld zijn.” Het verschil: BOLA is horizontaal (gebruiker A ziet data van gebruiker B), API5 is verticaal (gebruiker A voert admin-functies uit).

# Stap 1: Zoek admin endpoints
# Kijk in JavaScript broncode
grep -r "admin" app.js bundle.js

# Stap 2: Probeer ze als gewone gebruiker
curl -H "Authorization: Bearer USER_TOKEN" https://target.com/api/v1/admin/users
curl -H "Authorization: Bearer USER_TOKEN" https://target.com/api/v1/admin/settings
curl -H "Authorization: Bearer USER_TOKEN" -X DELETE https://target.com/api/v1/admin/users/1

# Stap 3: HTTP method tampering
# Misschien is GET beschermd maar POST niet?
curl -X POST https://target.com/api/v1/admin/users
curl -X PUT https://target.com/api/v1/admin/settings

GraphQL: de query-taal die te veel vertelt

GraphQL werd in 2015 door Facebook openbaar gemaakt, en het loste een reëel probleem op. Met REST API’s krijg je wat de server je geeft — soms te veel, soms te weinig. Met GraphQL vraag je precies wat je nodig hebt. Het is als het verschil tussen een buffet (REST) en een à la carte menu (GraphQL). Bij het buffet krijg je alles of niets; bij à la carte bestel je precies die drie ingrediënten die je wilt.

Het probleem is dat het menu soms te uitgebreid is. En dat de ober niet altijd controleert of je bepaalde gerechten wel mag bestellen.

Introspection: het schema opvragen

GraphQL heeft een ingebouwde functie genaamd introspection. Hiermee kun je het volledige schema opvragen: alle types, alle velden, alle queries, alle mutations. Het is alsof je een database kunt vragen: “Vertel me al je tabellen en kolommen.” In productie zou dit uitgeschakeld moeten zijn. In de praktijk is het dat vaak niet.

# Volledige introspection query
curl -X POST https://target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{__schema{queryType{name}mutationType{name}types{name kind fields{name type{name kind ofType{name}}}}}}"
  }' | python3 -m json.tool

# Compactere versie: alleen types en hun velden
curl -X POST https://target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{__schema{types{name fields{name}}}}"}'

# Tools
# GraphQL Voyager: visualiseert het schema als een interactieve graaf
# InQL: Burp Suite extensie voor GraphQL testing
# graphql-cop: detecteert veelvoorkomende GraphQL misconfiguraties

Als introspection is uitgeschakeld, kun je alsnog het schema reconstrueren via suggesties en foutmeldingen:

# Suggestie-exploitatie
# GraphQL geeft vaak "Did you mean..." suggesties bij typfouten
curl -X POST https://target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{use}"}'
# Response: "Did you mean 'user' or 'users'?"

# Brute force veldnamen
# Gebruik een wordlist van veelvoorkomende GraphQL-velden
for field in id name email password role admin token secret; do
  curl -s -X POST https://target.com/graphql \
    -H "Content-Type: application/json" \
    -d "{\"query\": \"{user{$field}}\"}" | grep -v "error"
done

GraphQL Injection en Authorization Bypass

Dezelfde autorisatieproblemen die REST API’s teisteren, bestaan in GraphQL — maar ze zijn moeilijker te detecteren omdat de query-structuur complexer is.

# BOLA in GraphQL: wijzig het ID in een query
query {
  user(id: "andere-gebruiker-uuid") {
    name
    email
    ssn
    creditCardNumber
  }
}

# Nested object traversal: volg relaties die je niet zou moeten zien
query {
  me {
    orders {
      merchant {
        allOrders {          # Alle bestellingen van alle klanten?
          customer {
            email
            address
          }
        }
      }
    }
  }
}

Query Depth en Batching: Denial of Service

# Diep geneste query (exponentiële complexiteit)
query {
  users {
    friends {
      friends {
        friends {
          friends {
            friends {
              name # Elke laag vermenigvuldigt het aantal database-queries
            }
          }
        }
      }
    }
  }
}

# Alias-based batching: dezelfde query 1000 keer in één request
query {
  a1: user(id: "1") { email }
  a2: user(id: "2") { email }
  a3: user(id: "3") { email }
  # ... tot a1000
}

# Array-based batching: meerdere operations in één HTTP request
[
  {"query": "mutation{login(user:\"admin\",pass:\"pass1\"){token}}"},
  {"query": "mutation{login(user:\"admin\",pass:\"pass2\"){token}}"},
  {"query": "mutation{login(user:\"admin\",pass:\"pass3\"){token}}"}
]
# Dit omzeilt rate limiting die per HTTP request telt

gRPC: Protocol Buffers en binaire API’s

Terwijl REST en GraphQL werken met JSON over HTTP, gebruikt gRPC Protocol Buffers over HTTP/2. Het is sneller, efficiënter, en — hier wordt het interessant — minder transparant. Je kunt een gRPC-call niet simpelweg in de browser bekijken. De data is binair gecodeerd. Het is alsof iedereen om je heen een taal spreekt die je niet verstaat — tot je de juiste tools hebt.

# gRPC reflection: ontdek beschikbare services
# (vergelijkbaar met GraphQL introspection)
grpcurl -plaintext target:50051 list

# Output:
# grpc.reflection.v1alpha.ServerReflection
# users.UserService
# orders.OrderService
# admin.AdminService   <-- interessant

# Beschrijf een service
grpcurl -plaintext target:50051 describe users.UserService

# Output:
# users.UserService is a service:
# rpc GetUser (GetUserRequest) returns (User);
# rpc ListUsers (ListUsersRequest) returns (stream User);
# rpc UpdateUser (UpdateUserRequest) returns (User);
# rpc DeleteUser (DeleteUserRequest) returns (Empty);

# Roep een method aan
grpcurl -plaintext -d '{"id": 1}' target:50051 users.UserService/GetUser

# Dezelfde BOLA-tests als bij REST:
grpcurl -plaintext -d '{"id": 2}' target:50051 users.UserService/GetUser

# Admin methods als gewone gebruiker:
grpcurl -plaintext -H "Authorization: Bearer USER_TOKEN" \
  -d '{"id": 1}' target:50051 admin.AdminService/DeleteUser

gRPC zonder reflection

Als reflection uitgeschakeld is, heb je de .proto bestanden nodig. Die kun je soms vinden in:

  • De broncode van de applicatie (als die open source is)
  • De JavaScript-client code (gRPC-Web compileert .proto naar JS)
  • De mobiele app (reverse engineer de APK/IPA)
  • Error messages die veldnamen onthullen

Praktische workflow: van ontdekking tot rapport

Stap 1: Passief verzamelen

Gebruik de applicatie normaal terwijl Burp Suite als proxy draait. Elke API-call wordt automatisch vastgelegd. Na tien minuten gebruik heb je een bijna complete API-map.

Stap 2: Documentatie importeren

Importeer de Swagger/OpenAPI spec in Postman of Burp. Dit geeft je ook de endpoints die je tijdens normaal gebruik niet hebt geraakt — admin-functies, batch-operations, webhook-configuratie.

Stap 3: Autorisatie-matrix bouwen

Maak een tabel met endpoints op de rijen en rollen op de kolommen (anoniem, gebruiker, admin). Test elk kruispunt: kan een gebruiker admin-endpoints bereiken? Kan een anonieme bezoeker gebruiker-endpoints bereiken?

Endpoint                    | Anon | User | Admin
--------------------------- | ---- | ---- | -----
GET  /api/v1/users          | 401  | 200  | 200
GET  /api/v1/users/:id      | 401  | 200* | 200   (* alleen eigen profiel?)
PUT  /api/v1/users/:id      | 401  | 200* | 200   (* alleen eigen profiel?)
GET  /api/v1/admin/users     | 401  | 403? | 200   (test dit!)
POST /api/v1/admin/settings  | 401  | 403? | 200   (en dit!)
DELETE /api/v1/users/:id     | 401  | 403? | 200   (en zeker dit!)

Stap 4: Diepte-tests per kwetsbaarheid

Nu je de breedte hebt afgedekt, ga je de diepte in. Voor elk endpoint dat je hebt gevonden:

  1. BOLA/IDOR: wijzig alle ID’s en UUID’s
  2. Mass Assignment: stuur extra velden mee
  3. Injection: test parameters op SQLi, NoSQLi, Command Injection
  4. Rate Limiting: hoeveel requests per minuut kun je doen?
  5. Input validatie: extreem lange strings, negatieve getallen, speciale tekens

Stap 5: Rapportage

API-bevindingen rapporteer je met:

  • Het volledige HTTP request (met token geredigeerd)
  • De response die de kwetsbaarheid bewijst
  • CVSS 4.0 score
  • OWASP API categorie (API1-API10)
  • Concrete remediatie: welke autorisatiecheck ontbreekt, waar in de code

API Pentest Checklist

CategorieTestOWASP
VerkenningSwagger/OpenAPI spec ophalen
VerkenningEndpoint fuzzing met wordlist
VerkenningOude API-versies (v1, v2, beta)API9
AuthnEndpoints zonder authenticatieAPI2
AuthnToken na logout nog geldig?API2
AuthnToken expiry gerespecteerd?API2
AuthzBOLA: wijzig ID in elk endpointAPI1
AuthzAdmin endpoints als gebruikerAPI5
AuthzHTTP method switching (GET→POST)API5
DataExcessive data in responsesAPI3
DataMass Assignment in PUT/PATCHAPI3
RateBrute force op loginAPI4
RateBrute force op OTP/resetAPI4
InjectionSQLi in query parametersAPI8
InjectionNoSQLi (MongoDB operators)API8
ConfigCORS misconfiguratieAPI8
ConfigVerbose error messagesAPI8
ConfigDebug mode / stack tracesAPI8

Microservices-specifieke kwetsbaarheden

Service-to-service authenticatie

In microservices communiceren interne services via API's. De authenticatie varieert van niets (trust the network) tot mTLS. Test altijd of interne endpoints bereikbaar zijn zonder authenticatie via SSRF of vanuit een gecompromitteerde pod.

# Interne endpoints zonder auth
curl http://internal-user-service:8080/api/users
curl http://internal-admin-service:8080/api/admin/config

# API Gateway bypass: direct naar backend
# Via SSRF of vanuit het interne netwerk
nmap -p 8080-8090 10.0.0.0/24
curl -H "X-User-ID: admin" -H "X-Authenticated: true" http://backend:8080/admin

GraphQL geavanceerd

# Batch query abuse voor rate limit bypass
curl -X POST http://target.com/graphql -H "Content-Type: application/json" \
  -d '[{"query":"mutation{login(email:\"admin@t.com\",pass:\"p1\"){token}}"},
       {"query":"mutation{login(email:\"admin@t.com\",pass:\"p2\"){token}}"}]'

# Field suggestion exploitation (schema reconstrueren zonder introspection)
curl -X POST http://target.com/graphql -H "Content-Type: application/json" \
  -d '{"query":"{systemHe}"}'
# "Did you mean 'systemHealth'?"

# Tools: InQL Scanner (Burp), graphql-cop, clairvoyance

Op de hoogte blijven?

Ontvang nieuwe hoofdstukken en updates per e-mail.