Cupid's Matchmaker
“No algorithms. No AI. Just real human matchmakers.”
// overview
The app is a Flask-based personality survey at http://<TARGET_IP>:5000. The tagline hints that “real humans” review every submission — meaning a headless browser bot views stored user input. If the input isn't sanitised, stored XSS lets us execute JavaScript in the bot's context and exfiltrate sensitive data.
// reconnaissance
The site has a /survey form with fields: name, age, gender, seeking, ideal_date, describe_yourself, looking_for, dealbreakers.
Submitted data is stored and later reviewed by an automated bot (Headless Chrome). The /admin endpoint exists but redirects to /login — no direct access without a valid session.
// exploitation
$Step 1 — Start a listener
$Step 2 — Inject the XSS payload
Fill out the survey and put the following payload in any field (e.g. describe_yourself):
This fetches the bot's document.cookie, Base64-encodes it, and sends it to your listener.
$Step 3 — Submit and wait
Submit the survey. The bot reviews it shortly after, executing the payload. Your listener receives a request like:
$Step 4 — Decode the cookie
The cookie value is Base64-encoded. Decode it:
Output:
// flag
// key takeaways
- >Stored XSS in user-submitted content that an admin/bot views is a critical vulnerability.
- >HttpOnly cookies would have prevented
document.cookieaccess — the flag cookie lacked this flag. - >Always sanitise and encode user input before rendering. A single unsanitised field is enough for full compromise.