A Leftover Test Parameter Loads Attacker Code on a Real Signup Page
The Risk
An attacker could craft a link to this trading platform's real signup page that quietly swapped the genuine sign-up form for a look-alike the attacker controlled. Because the page was on the company's own genuine address with the company's own valid security padlock, it passed every trust check a careful person would make. Anyone who opened the link and typed in an email and password to create an account handed those exact details straight to the attacker, in plain text, before the form was even submitted. Those captured details are real account credentials, immediately usable against the victim's other accounts too.
The Vulnerability
The signup page accepted a leftover test parameter on its query string. That parameter was intended to point the page at an internal test asset host, but the validation that was supposed to keep it pointed at company-owned hosts was a substring match rather than a strict, anchored check.
The check looked for a fixed pattern anywhere inside the supplied hostname. Because it was not anchored to the start and end of the host, any attacker hostname that simply contained that pattern as a substring passed validation. The page then appended a fixed path to the attacker hostname and loaded it as a script. The signup response also sent no Content-Security-Policy, so nothing constrained the external script load.
The injection was reflected, not stored: loading the signup page without the parameter reverted to the legitimate script. All signup locale paths fired.
The Attack
Credential capture
The platform renders its real signup form inside a cross-origin frame specifically so the outer page cannot read those fields. This flaw defeats that control. Because the attacker owns the injected script that is responsible for loading the frame, it can instead render an identical clone form directly in the genuine page, where every field is fully readable.
- The attacker sends a victim a crafted link to the genuine signup page carrying the test parameter set to an attacker host.
- On load, the page loads the attacker script in the genuine origin and replaces the real embedded form with a pixel-faithful clone.
- The victim types an email, username, and password and clicks create account.
- The clone records every field and beacons the captured values, plus all readable cookies and the genuine origin, to an attacker server.
- The clone then shows a benign "something went wrong, please try again" message and redirects to the clean signup page, so the victim re-registers in the genuine form with the same password they had already chosen.
Execution in the genuine origin was independently confirmed with a console probe showing the page origin and the injected script source pointing at the attacker host.
The Impact
An attacker who sends a crafted link runs arbitrary JavaScript in the genuine origin against any visitor who opens it, with no authentication and no victim action beyond clicking. The captured email, username, and cleartext password are the victim's account credentials, captured on a genuine domain with a valid certificate. Those values are immediately usable for credential stuffing and password reuse against the victim's other accounts, and they form a high-fidelity basis for targeted fraud given the verified email, phone, and demonstrated intent to fund a trading account. This holds whether or not the signup is ever completed.
The severity is bounded to High rather than Critical because the attacker script could not silently complete registration from the injected origin. The registration API lives on a different host whose cross-origin policy and a custom required header force a preflight that denies the automated submission, and the attacker cannot pass the victim's email verification. Theft of an existing logged-in session was also not demonstrated, since that session cookie is not readable and cross-origin reads of the account host are blocked. The demonstrated impact is the compromise of the account credentials themselves.
Remediation
- Remove the test parameter from production builds entirely. It serves no purpose to real users and is the entire attack surface.
- If a similar parameter must remain, validate it strictly: parse it as a URL, require the secure scheme, and require an exact company-owned host rather than a substring match. Anchor any pattern check to the start and end of the host.
- Add a Content-Security-Policy with an explicit script-source allowlist so an unexpected external origin cannot load a script even if validation is bypassed.