€150 Bounty: Chaining Vulns to fully Exploit CORS Misconfiguration

Fabian Cruz
3 min readMay 1, 2024



The program comprised several subdomains. Following a straightforward reconnaissance using subfinder, httpx, and Aquatone, a specific target stood out in the Aquatone report. This particular target featured a login distinct from the main application within the scope.

Upon analyzing the target, I uncovered multiple vulnerabilities, including:

1. URL Information Leak
2. CORS Misconfiguration
3. Exposed Credentials

By chaining these three vulnerabilities together, I successfully executed a one-click Account Takeover, seizing control of the victim’s session tokens.

To uphold confidentiality, the term “target” will be employed to conceal the actual company’s identity.


The attack is chained with 3 steps/stages/phases.

Getting authorize_session_id

When a GET request is made to https://auth.target.com/login, the response or the redirect sets the value for the URL parameter authorize_session_id to https://auth.target.com/login?authorize_session_id=<auth_session_id>.

(Note: .withCredentials() was set to true for this XMLHttpRequest.)

(response_type, client_id and redirect_uri was not required to obtain session id)

Getting the code

After obtaining the auth_session_id, the value is passed to another endpoint to get the code.

Two values, auth_session_id and client_id, are required to get the code. The client_id value (5952XXXXXXXXe0aa) remained static regardless of the network, session, region, device, and can be used to generate the code for anyone.

Both the client_id and auth_session_id are given to the following URL, and the result would be:


The redirect or response will have the code in the URL as


(Note: .withCredentials() was not set for this XMLHttpRequest.)

Getting the session tokens

Once the code is obtained, a final request is made to get the session tokens.

Again, two parameters are required to complete this attack:

1. code
2. Authorization header

The code obtained from the previous attack must be fed into the following URL:


When this XMLHttpRequest is made, a header is required to be set:

req.setRequestHeader('Authorization', 'Basic NTk1MjNXXXXXXXXXXXXkNWNjYzdjYjEzOA==');

Like the client_id in the previously mentioned attack, this credential (NTk1MjNXXXXXXXXXXXXkNWNjYzdjYjEzOA==) was static as well. This string was base64 encoded with the `client_id` and another unknown identifier.

When the request is successfully made, the response will hold the access_token and refresh_token for controlling a victim’s session.

(Note: `.withCredentials` was set to true for this XMLHttpRequest.)


This process was automated with a custom CORS exploit script that can be found (here) (a very sloppy version).

The script required a lot of tweaking, and it was made recursive because this attack will work only when the victim has the attack script already opened and running in the background while the victim is logging in.

The target application only had a working authentication app and nothing past the end of the authentication process (like a dashboard, settings, profile). It was just blank and required the company’s credentials to operate further.


Reported — November 24th, 2021

Triaged — November 29th, 2021

Bounty Awarded — December 2th, 2021

Follow me on Twitter: 124v3n012

Buy me a coffee: https://www.buymeacoffee.com/r4v3n0r