Cyber Security Blog

Stay ahead of the curve with industry trends, cutting edge tech and inventive strategies.

Case Study: Lessons from a Modern XSS Cross Site Scripting Attack

We recently ran a web app pen test and found a flaw that proves old vulnerabilities are still alive and well in modern apps.

The application we were testing looked well-built. A slick Single Page Application (SPA) with OpenID Connect (OIDC) authentication — the kind of setup you’d expect to be airtight. But one small oversight left the application exposed.

A textbook DOM (Document Object Model) based Cross-Site Scripting (XSS) bug was sitting quietly in the code, waiting to be triggered. And once it was, it gave us everything we needed to steal a user’s authentication tokens. With those tokens in hand, we could log in as that user, bypassing passwords entirely.

If this sounds like something that should have been left behind in the early 2000s, you’re right — but the truth is, old vulnerabilities never really go away. They resurface when assumptions are made and baseline protections are missed.

In this blog, we’ll walk through exactly how the exploit worked, why it’s still relevant in 2025, and the practical steps you can take to make sure it doesn’t happen on your watch.

Inside the App: Where the Weakness Lurked

On the surface, the client’s application ticked all the right boxes. It was a modern Single Page Application (SPA), designed for speed and a smooth user experience. Authentication was handled through OpenID Connect (OIDC), a trusted and widely used protocol.

Once logged in, the application stored the user’s authentication tokens in the browser’s sessionStorage — a temporary storage area that keeps data for as long as the tab is open and is fully accessible to JavaScript.

At first glance, this might seem harmless. sessionStorage clears itself when the browser closes, and unlike cookies, it doesn’t automatically get sent with every request. Many developers see it as a safe and convenient option for storing tokens in SPAs.

But there’s a catch. sessionStorage is fully accessible to JavaScript running in the browser. If an attacker manages to inject their own script — through a vulnerability like Cross-Site Scripting (XSS) — they can read those tokens directly. No extra hurdles, no password guessing, no brute-force attempts.

In OIDC, an access token lets you interact with protected APIs on behalf of the user, while an ID token proves who that user is. If stolen, they can be used to impersonate the victim, access their data, and perform any action they’re allowed to do — until the tokens expire. In some setups, that could mean hours of access. In poorly configured ones, it could mean much longer.

In this case, the combination of storing valuable tokens in sessionStorage and a hidden XSS vulnerability created the perfect conditions for a full account takeover. All it needed was the right payload to bring the problem to life.

From Flaw to Full Takeover: How the XSS Script Attack Unfolded

Once we spotted the risky token storage, the next step was to see if it could be exploited. It didn’t take long to find the way in.

While testing different inputs, we discovered that the application was taking what we typed and inserting it directly into the DOM without proper checks. Specifically, it used Aurelia’s innerhtml.bind feature — a method that injects raw HTML into the DOM. When used with untrusted input, this can introduce a serious security risk — including the potential for cross-site scripting (XSS) attacks — as it allows an attacker to inject and execute arbitrary HTML or JavaScript code in the user’s browser.

Here’s how the attack came together:

1. Finding the opening – We entered crafted text into an input field, knowing the app would display it back to us.

3. Reading the tokens – The JavaScript accessed sessionStorage and pulled out the OIDC tokens stored there.

4. Sending the tokens out – The script sent the stolen tokens to a server we controlled.

5. Logging in as the victim – With those tokens, we could impersonate the user, bypassing the need for their password entirely.

This chain of events is a classic example of how a single weak point — in this case, stored XSS — can be the first domino that knocks over the rest of your security controls.

Why Old Bugs Still Bite in 2025

Cross-Site Scripting has been around for decades, yet it still shows up in modern applications.

Here’s why:

Shutting the Door on XSS and Token Theft

Stopping this kind of attack isn’t about finding a single silver bullet. It’s about layering defences so that even if one measure fails, others are there to protect you.

1. Fix the XSS

  • Validate and sanitise all user input on the server before it’s processed.
  • Encode output so any potentially dangerous characters are displayed as text, not executed as code.
  • Avoid risky methods like innerhtml.bind when handling untrusted data. Use safer alternatives such as text.bind.

2. Store Tokens More Securely

  • Prefer secure cookies with the HttpOnly, Secure, and SameSite flags — making them inaccessible to JavaScript.

  • Consider storing tokens in memory rather than in persistent browser storage.

3. Add Security Headers

4. Test Regularly

A single overlooked coding choice was all it took to open the door in this case study. By combining secure coding practices, strong browser protections, and ongoing testing, you make that door much harder to find — and even harder to force open.

Lessons Cyber Security Leaders Can’t Ignore

This case study isn’t just about one vulnerable application — it’s a reminder of how quickly small oversights can escalate into full-scale compromise. For Cyber Security leaders, the value lies in recognising where the gaps appear and ensuring the right controls are in place before an attacker has the chance to exploit them.

Key points to take away:

By focusing on these principles, leaders can better prepare their teams and their applications for the threats that persist — even in today’s most modern environments.

Modern Apps, Old Mistakes:

Even the most up-to-date applications can fall to vulnerabilities we’ve known about for decades. The difference between a secure system and a compromised one often comes down to attention to the fundamentals.

Don’t wait for an attacker to find the gaps in your defences. Let our experts uncover them first with our  web application penetration testing services.

Contact Equilibrium Security on 0121 663 0055 or email enquiries@equilibrium-security.co.uk to discuss how penetration testing can strengthen your security posture.

Ready to achieve your security goals? We’re at your service.

Whether you are a CISO, an IT Director or a business owner, Equilibrium has the
expertise to help you shape and deliver your security strategy.

About the author

Amelia is Head of Marketing at Equilibrium Security, with a focus on Cyber Security content since 2016. She combines deep marketing expertise with hands-on knowledge of the cyber threat landscape to create clear, practical content that helps businesses improve awareness, reduce risk, and embed security best practice across their teams.
Amelia Frizzell
Head Of Marketing and Operations

Latest posts