Skip to main content

Command Palette

Search for a command to run...

Chain of Three Client-Side Vulnerabilities Leads to One-Click Account Takeover

Updated
3 min read
Chain of Three Client-Side Vulnerabilities Leads to One-Click Account Takeover

Hello, hackers. Last year, Mehrad and I discovered an account‑takeover vulnerability by chaining three client‑side vulnerabilities. Let’s dive in.

Understanding the Target

Target was a single web application; the scope was https://redacted.com, so we focused on it and started our recon. First of all, we checked the target’s authentication mechanism. When a user wants to log in, they send credentials and the site returns an initial access cookie. After login, the user sends a request to redacted.com/xxx/?action=get-token with the cookie and gets an access token. This token is then used to perform user activities. Also, the initial cookie had a SameSite=Strict policy, so our requests from third parties to this website couldn’t contain this cookie.

Website authentication flow:

CORS Implementation Detection

By analyzing the token‑receiving behavior, we noticed that the endpoint redacted.com/xxx/?action=get-token has a CORS policy that only allows *.redacted.com origins. If we send a request from a different origin, the endpoint does not return the token in the response. Even if it did return a token, we could not exploit it due to the cookie’s SameSite flag.

So far, we have an endpoint that returns a JWT token via cookie, and CORS is enabled for all subdomains.

Self‑XSS Detection

While exploring the website, we found that the first_name parameter was vulnerable to XSS. We tried to escalate it to something impactful but couldn’t, since the site doesn’t show the first name to other users (it might appear in the admin panel, but we didn’t test that). There are a few general ways self‑XSS could be escalated for example, abusing caches or chaining with CRLF/CSRF but I’m not going into those here. Quickly, I had the idea to log the victim into our account (the one whose display name contained the XSS payload) and trigger the XSS. That didn’t have any impact either, since the payload only executed in our own account. In other words, we were just exploiting ourselves. So far, we’ve got a useless self‑XSS that couldn’t be made impactful, plus an endpoint that returns a JWT via a cookie and has a CORS policy allowing all subdomains.

Different approach & CSRF

We stopped there. We didn’t have any idea how to proceed, so we tested the site from a different angle. We performed subdomain enumeration and saved subdomains with active HTTP services. One of them caught our attention: dev.redacted.com. We opened it immediately; it looked similar to the production app, so we registered there. During testing we discovered the first_name parameter was also vulnerable to XSS, as on the main site. We wondered what would happen if we logged a user into our account on the dev subdomain and executed an XSS payload against them.

Attack flow:

Let’s explain steps one by one:

  1. The attacker sends a CSRF link to the victim. When the victim opens it, they are automatically logged into the attacker’s account on dev.redacted.com.

  2. The attacker had previously set an XSS payload in the first_name parameter. After the victim logs in, the payload executes in the victim’s browser.

  3. The XSS payload sends a request to redacted.com/xxx/?action=get-token with the victim’s cookie to retrieve an authentication token. Because the request originates from dev.redacted.com, the SameSite attribute does not prevent the cookie from being sent. Since the production and development sites use distinct authentication systems, the victim remains logged into their own account on redacted.com.

  4. The exploit extracts the authentication token from the response and sends it to the attacker’s server.

  5. The attacker replaces the token on the website and logs into the victim’s account.

The end

When you find something that seems useless or without impact, don’t stop there be more curious, explore further, think differently, and approach the target website from a new angle. I hope this write-up was helpful to you.

You can follow me and Mehrad on X (formerly Twitter): @alial1shan and @m3hradd