IDOR - Insecure Direct Object Reference
Insecure Direct Object Reference (IDOR) ist eine Zugriffssteuerungsschwachstelle bei der eine Anwendung direkte Referenzen auf interne Objekte (Benutzer-IDs, Datei-Pfade, Datenbankschlüssel) ohne Autorisierungsprüfung verwendet. Angreifer manipulieren diese Referenzen um auf fremde Daten zuzugreifen. IDOR ist Teil von OWASP A01:2021 (Broken Access Control) und gehört zu den häufigsten kritischen Schwachstellen in Web-Applikationen und APIs.
IDOR ist deceptively simple - und wurde in Millionen-Euro-Bug-Bounty-Programmen vieler Mal prämiert. Ein User-ID-Parameter von ?user=123 auf ?user=124 zu ändern und damit auf fremde Kontodaten zuzugreifen: das ist IDOR in seiner reinsten Form. Obwohl simpel erklingt, verursacht IDOR regelmäßig massive Datenschutzvorfälle. Über IDOR wurden bei verschiedenen Unternehmen Millionen von Kundendatensätzen, Kreditkarteninformationen und private Nachrichten unbefugt abgerufen.
IDOR-Typen und Beispiele
Häufigste IDOR-Manifestationen:
1. Numerische IDs in URLs:
# Angreifer ist eingeloggt als User 123:
GET /api/invoices/456 → sieht Rechnung von User 456!
GET /profile/789 → sieht Profil von User 789!
GET /download/file/1001 → lädt Datei anderer User!
2. IDs in Request-Body:
POST /api/update-profile
{"userId": 456, "email": "angreifer@evil.com"} ← fremde User-ID!
3. IDs in HTTP-Headern:
GET /api/dashboard
X-User-ID: 456 ← manipulation!
4. IDOR in Dateidownloads:
GET /download?file=../users/456/private-docs/vertrag.pdf
GET /invoice?id=INV-2026-0042 → andere Rechnungsnummer!
5. IDOR in API-Keys/Tokens:
GET /api/webhooks/webhook_abc123 → fremde Webhook-Config!
DELETE /api/sessions/sess_xyz789 → fremde Session terminieren!
6. IDOR mit Hash/UUID (aber Rate-Limitlos):
GET /share/a3f5c8e2-1234-5678-abcd-ef0123456789
→ UUIDs sind nicht unrateable wenn Generierung vorhersagbar!
→ Oder: Endpoint ist intern und UUID liegt im Quellcode!
7. Mass Assignment + IDOR:
PUT /api/user/123
{"role": "admin"} → Privilege Escalation via IDOR!
{"balance": 99999} → Kontoguthaben manipulieren!
8. IDOR in GraphQL:
query {
user(id: "456") { ← andere User-ID!
email, phone, address
}
}
# Wenn kein Object-Level Authorization: fremde Daten sichtbar!
Reale Beispiele (Bug Bounties):
Uber (2014): IDOR ermöglichte Einsicht in alle Fahrerprofile
Tesco (2020): Order-IDOR - jede Bestellnummer abrufbar
Instagram: Mass IDOR über Follower-API → Millionen Profile
PayPal: IDOR in Invoice-System → fremde Rechnungen einsehbar
IDOR Erkennung
Testing-Methodik im Pentest:
Schritt 1: Parameter identifizieren
→ Alle Objekt-Referenzen in Requests finden:
- Numerische IDs: /api/order/123
- Alphanumerisch: /doc/AB123CD
- Hashes: /file/md5hash
- Base64-kodierte IDs: /profile/dXNlcl8xMjM=
- Sequentielle IDs: INV-2026-0001, INV-2026-0002
- UUIDs: /webhook/550e8400-e29b-41d4-a716-446655440000
Schritt 2: Zwei Konten anlegen (User A + User B)
User A: account_a@test.com / Ressource-ID: 1001
User B: account_b@test.com / Ressource-ID: 1002
# Mit User B eingeloggt:
GET /api/resource/1001 → Bekommt User A's Ressource?
Schritt 3: Vertikale IDOR (andere Rolle)
Normaler User versucht Admin-Endpunkte:
GET /api/admin/users/123 → mit normalem User-Token
Schritt 4: API-Dokumentation analysieren
→ Swagger/OpenAPI Docs: welche Parameter existieren?
→ JavaScript-Dateien: interne API-Endpunkte?
→ Backup-Dateien: /api.md, /api.txt, /swagger.json
Burp Suite Intruder für IDOR:
# Parameter "id" automatisch iterieren:
GET /api/user/§1§
# Payloads: 1, 2, 3, ... 1000
# → Filter: response length != Fehler-Response
IDOR in API-Responses versteckt:
# Manchmal sind IDs in Responses versteckt:
GET /profile
{
"user": "alice",
"_links": {
"invoice": "/api/invoices?userId=123" ← ID in Link!
}
}
Sicheres Design gegen IDOR
Gegenmittel - Authorization auf Object-Level:
1. Object-Level Authorization (Best Practice):
# NICHT:
def get_invoice(invoice_id: int):
return Invoice.get(invoice_id) # Kein Besitzer-Check!
# GUT:
def get_invoice(invoice_id: int, current_user: User):
invoice = Invoice.get(invoice_id)
if invoice.user_id != current_user.id:
raise PermissionDenied("Nicht autorisiert")
return invoice
2. Indirect Object References (Mapping):
# Statt direkte DB-IDs: session-spezifische Referenzen
# Beim Login: Map erstellen
session['resource_map'] = {
'doc1': actual_db_id_1234,
'doc2': actual_db_id_5678
}
# URL: /download?ref=doc1 (nicht /download?id=1234!)
# Server löst 'doc1' → 1234 auf (session-spezifisch!)
3. Kryptographische Token für Ressourcen:
# HMAC-signierte Ressource-Tokens:
import hmac, hashlib
def generate_resource_token(user_id: int, resource_id: int, secret: str) -> str:
message = f"{user_id}:{resource_id}".encode()
return hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
# Validierung:
def validate_resource_token(user_id, resource_id, token, secret):
expected = generate_resource_token(user_id, resource_id, secret)
return hmac.compare_digest(token, expected) # Timing-safe!
4. UUIDs als Alternative (mit Vorsicht!):
# UUID v4 ist zufällig (nicht rate-bar) - aber:
# → URL/Log-Exposure Problem!
# → Sicherheit durch Obscurity - kein echtes AuthZ!
# UUIDs ERSETZEN NICHT Authorization - sie ergänzen sie!
5. Middleware/Policy-basierte AuthZ:
# CASL (JavaScript):
ability.can('read', Invoice, { userId: currentUser.id })
# OPA (Open Policy Agent):
allow {
input.user.id == input.resource.owner_id
}
# Django Rest Framework:
class IsOwner(BasePermission):
def has_object_permission(self, request, view, obj):
return obj.user == request.user
Automatisches IDOR-Testing in CI/CD:
# Tool: pytm (Threat Modeling) + Tests
# Tool: Semgrep Rules für IDOR-Pattern
# GitHub Action: DAST Scan auf Staging
IDOR vs. verwandte Schwachstellen
IDOR vs. andere Broken Access Control Typen:
IDOR (Horizontal Privilege Escalation):
→ Zugriff auf Ressourcen ANDERER User (gleiche Rolle)
→ Beispiel: User A sieht User Bs Rechnungen
Vertikale Privilege Escalation:
→ User greift auf Admin-Funktionen zu
→ Beispiel: normaler User aktiviert Admin-Dashboard
Mass Assignment:
→ Felder setzen die nicht erlaubt sind
→ Beispiel: {"role": "admin"} in User-Update
→ Oft kombiniert mit IDOR!
Forced Browsing:
→ Direkte URL-Eingabe zu geschützten Ressourcen
→ Beispiel: /admin/users ohne Login
API-Level IDOR (BOLA - Broken Object Level Authorization):
→ OWASP API Security Top 10 #1 (API1:2023)
→ Gleiches Konzept wie IDOR, aber in API-Kontext
→ Besonders gefährlich bei REST APIs (CRUD-Operationen!)
IDOR vs. BOLA:
IDOR: älterer Begriff, ursprünglich für Web-Apps
BOLA: OWASP API Security Term, meint dasselbe
Praxis: beide Begriffe werden synonym verwendet AWARE7 Leistungen zum Thema
Ausführlicher Wiki-Artikel
Access Control Modelle: DAC, MAC, RBAC, ABAC und Zero Trust
API-Sicherheit: OWASP API Top 10, Authentifizierung, Testing und Best Practices
18 Min. Lesezeit
Identity & Access Management (IAM): Identitäten sicher verwalten
12 min Lesezeit
Web-Applikations-Sicherheit: OWASP Top 10, Security Testing und WAF
20 min Lesezeit