🧠 TL;DR During a security assessment, I discovered an XSS vulnerability in an application that used a blacklist filter. The app blocked <, >, ", and all common event handlers β€” but missed one sneaky handler: onauxclick. By leveraging dual reflection contexts (HTML + JavaScript) and a bit of syntax balancing, I managed to trigger XSS… with just a middle-click.

🎯 The Discovery While testing an "embedded view" parameter, I noticed something interesting. Whenever I injected test, it showed up twice in the response:

  1. Inside a value attribute (value="test")
  2. Inside a JavaScript block. That's when I knew β€” this parameter had potential.

But the app wasn't going to make it easy. Every time I tried <, >, ", or any event handler, it HTML-encoded my input. So no <script>, no onload, no onclick. Even alert() was getting stripped.

πŸ•΅οΈβ€β™‚οΈ The Observation Game I started testing combinations:

  1. alert() β†’ sanitized.
  2. prompt() β†’ sanitized.
  3. onload=, onerror=, onclick= β†’ all sanitized.
None

But when I entered just alert (without parentheses), it reflected as-is. Hmm… interesting.

Then I noticed something bigger β€” the value was also reflecting in the JavaScript context, not just the HTML attribute. So, if the HTML side is locked down… maybe I can balance the JS side instead?

🧩 The Breakthrough That's where the fun began. I carefully analyzed how the code around my reflection looked in JavaScript. With the right balance β€” no <, >, or " β€” I could make my injected text part of the JS logic.

But I still needed a trigger β€” something the filter hadn't blocked.

After testing multiple event handlers, I found one that slipped through the cracks: onauxclick β€” the event that fires when you middle-click.

So I tweaked my input, aligned it with the JS syntax, and tried a middle click…

None

Boom. XSS triggered. No fancy characters, no tags, just clever context control.

βš™οΈ Why It Worked 1) Dual Reflection Contexts β€” My input appeared in both HTML and JS, allowing code balancing in one while the other stayed encoded. 2) Weak Blacklist Filtering β€” The app only filtered known patterns, missing obscure ones like onauxclick. 3) Context-Based Exploitation β€” Instead of injecting HTML, I exploited the JavaScript context itself.

This wasn't just about writing payloads β€” it was about understanding how browsers parse data and how incomplete filters break.

🧱 How to Fix It (Developers, Listen Up πŸ‘€) 1) Use context-aware encoding, not generic HTML encoding. 2) Avoid inline event handlers β€” use addEventListener() instead. 3) Implement a strong Content Security Policy (CSP) β€” block inline scripts entirely if possible. 4) Validate and encode output, not just input.

πŸ”’ Final Thoughts Blacklists are like duct tape β€” they look like they fix things, but they don't hold up under pressure. When you rely on keyword blocking instead of proper context handling, you're just challenging attackers to find that one missing piece.

In this case, it was a middle-click event that made all the difference. So, next time someone says, "Our app is fully sanitized," just smile β€” and click your mouse wheel. πŸ˜‰

🏷️ Tags: #XSS #CyberSecurity #AppSec #WebHacking #BugBounty #EthicalHacking #WebSecurity #JavaScript #SecurityResearch #Hackers