IDOR and Forced Browsing: Enumerating Objects Nobody Should Reach
Started with robots.txt, which named /admin and /singlestatus as disallowed (a map of what to look at, not a control). ffuf with a large wordlist discovered admin, chat, contact, kb, status, and a builds path that returned a directory listing exposing a full Docker build log (installed packages, base image, build stages). The chatbot at /chat saved transcripts on the 'save' command to /chatlogs/chatlog-<id>.txt with a predictable four-digit ID and no auth. Enumerating IDs with seq piped into ffuf, filtering out the baseline 500 error (-fc 500), found live logs at 2305, 5492, 7127, 7341, and 9653, each another user's full conversation, in 10,000 requests over five seconds.
Commands
1. Read robots.txt
curl on robots.txt showed AI-crawler blocks and, for all agents, Disallow: /admin and Disallow: /singlestatus. robots.txt does not protect anything; it is a list of the paths the site most wants hidden, which makes it the first place to look.
curl http://support.falsimentis.com/robots.txt
2. Discover content with ffuf
ffuf fuzzed the URL path with a 128k-word list at ~2,200 requests/sec. Hits: admin, chat, contact, kb, status (all 200), and builds (302). The FUZZ keyword marks where each wordlist entry is substituted.
ffuf -w combined_words.txt -u http://support.falsimentis.com/FUZZ
3. Investigate the builds directory listing
curl -v on /builds/ returned an 'Index of /builds' directory listing exposing build.log (80 KB) and build.log.old. Reading build.log leaked the entire Docker build: python:3.7-slim base, installed packages (including fping and netcat, relevant to the sibling command-injection lab), and every build stage.
curl -v http://support.falsimentis.com/builds/ curl -v http://support.falsimentis.com/builds/build.log
4. Trigger the chatbot save
The /chat bot offered a 'save' command. Typing save returned 'Chat history saved!' and wrote the transcript to /chatlogs/chatlog-7341.txt. curling that file returned the transcript: a predictable four-digit ID, served with no authentication.
# in the chat UI: type 'save' curl http://support.falsimentis.com/chatlogs/chatlog-7341.txt
5. Enumerate the log IDs
seq generated IDs piped into ffuf as a stdin wordlist. The first pass showed every nonexistent ID returned 500, so -fc 500 filtered that baseline out. Sweeping 0-9999 found live logs at 2305, 5492, 7127, 7341, and 9653 in 10,000 requests over five seconds.
seq -w 0 9999 | ffuf -w - -u http://support.falsimentis.com/chatlogs/chatlog-FUZZ.txt -fc 500
6. Retrieve another user's log
curling chatlog-2305.txt returned a complete conversation belonging to a different user. No credentials, no session, no ownership check: a predictable ID was the only thing between an anonymous request and another user's data. That is IDOR.
curl http://support.falsimentis.com/chatlogs/chatlog-2305.txt
Key Findings
- robots.txt disclosed /admin and /singlestatus as sensitive paths
- /builds directory listing leaked a full Docker build log
- Chatbot saved transcripts to predictable /chatlogs/chatlog-<id>.txt with no auth
- seq + ffuf -fc 500 enumerated 10,000 IDs in 5 seconds, exposing 5 users' logs
Security Controls
- Server-side authorization on every direct object reference
- Unguessable identifiers (UUIDs) instead of sequential IDs
- Directory-listing disabled; artifacts out of web root
- Rate limiting and enumeration detection
- Not treating robots.txt as access control