Simple XSS Using Alert Obfuscation

3 min read

A write-up on finding a Cross-Site Scripting vulnerability using an alert obfuscation payload to bypass RegEx filters.

XSSBugBountyWrite-Up
Simple XSS Using Alert Obfuscation

Hello Fellow Hackers,

In this article, I'll be sharing one of my recent findings - a Reflected XSS vulnerability I discovered by leveraging an alert obfuscation payload to bypass input filters.

The Target

I was hunting on a target (let's call it redacted.com). The application was essentially a job vacancy search portal with a search box for filtering vacancies.

Naturally, the search box became my first point of interest for testing XSS.

What Is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a type of injection attack in which an attacker injects malicious scripts into content served by an otherwise trusted website. It occurs when an application includes untrusted data in its output without proper validation or encoding, allowing the injected code to execute in a victim's browser.

Initial Attempts

I started with some standard XSS payloads - the usual suspects like <script>alert(1)</script>, event handlers, and common bypasses.

No luck. The application appeared to have some form of input filtering in place.

The Breakthrough - Alert Obfuscation

Then I recalled a tweet by lutfumertceylan about an XSS payload that uses alert obfuscation to bypass RegEx-based filters.

The idea is simple: instead of using the literal string alert, you generate it dynamically using JavaScript's toString() method with a custom radix - effectively hiding the function name from pattern-matching filters.

I crafted the following payload and submitted it to the search box:

1"><img src="X" onerror=top[8680439..toString(30)](1337)>

Boom! 💥

Payload Triggered

The payload triggered successfully - the alert box popped.

How the Payload Works

Let's break down each part of the payload:

  1. <img src="X"> - Sets an invalid image source intentionally, which causes the browser to fire the onerror event handler.

  2. top - Returns the topmost window in the hierarchy of window objects. This is used to access global functions.

  3. 8680439..toString(30) - This is the core of the obfuscation. JavaScript's Number.prototype.toString(radix) converts a number to a string representation in the specified base. Converting 8680439 to base 30 produces the string "alert".

  4. top["alert"](1337) - The bracket notation calls window.alert(1337), triggering the alert without ever writing the literal word "alert" in the payload.

The final effective payload is:

<img src="X" onerror=top[8680439..toString(30)](1337)>

This technique is particularly effective against RegEx-based WAFs and input filters that blacklist common function names like alert, prompt, or confirm.

Report Timeline

  • 08-Dec-2020 - Bug reported to the concerned company.
  • 09-Dec-2020 - Received acknowledgement; fix deployed.
  • 09-Dec-2020 - Retested and confirmed the fix.
  • 10-Dec-2020 - Rewarded.

Key Takeaways

  • RegEx-based input filters are not sufficient for preventing XSS. Obfuscation techniques can easily bypass pattern matching.
  • Context-aware output encoding is the proper defense against XSS, not input blacklisting.
  • Always think creatively - if standard payloads are blocked, there are almost always alternative representations.

Thanks for reading!

Back to Blog