šŸš€Introducing Bright Star: AI-Powered, Autonomous Security Testing & Remediation! Learn more>>

Back to blog
Published: Aug 16th, 2023 /Modified: Mar 25th, 2025

How I bypassed an Imperva WAF and obtained XSS

Time to read: 5 min
Avatar photo
Gocha Okradze

Summary:

Cross-Site Scripting (XSS) is a type of security vulnerability commonly found in web applications. It occurs when a web application allows malicious actors to inject malicious code (usually JavaScript) into web pages viewed by other users. This allows the attacker to execute arbitrary code within the context of another user’s browser, potentially stealing sensitive information, manipulating content, or performing actions on behalf of the victim user.

XSS vulnerabilities can be classified into three main types:

1. Stored XSS (Persistent XSS):

In this type of XSS, the malicious code is permanently stored on the web server, often in a database. When a user requests the compromised page, the server includes the malicious code in the response, which then gets executed by the victim’s browser. This is particularly dangerous as the malicious code affects every user who accesses the compromised page.

2. Reflected XSS:

Reflected XSS involves injecting malicious code into a web application’s input (such as a search bar), and then the application reflects that code back to the user as part of the response. The attacker often tricks the victim into clicking a malicious link that contains the injected code. Once the victim clicks the link, the malicious code executes in their browser. Unlike stored XSS, this attack is not persistent and only impacts users who interact with the malicious link.

3. DOM-based XSS:

DOM-based XSS exploits vulnerabilities in the Document Object Model (DOM) of a web page. Instead of modifying the actual page content on the server, the attacker manipulates the DOM elements using JavaScript to execute malicious code in the victim’s browser. This type of XSS doesn’t rely on server responses to deliver the payload, making it harder to detect.

Mitigating XSS vulnerabilities involves several security practices:

1. Input Validation and Sanitization:

Web applications should validate and sanitize user inputs to prevent any malicious code from being executed. Input validation involves checking that user inputs match expected formats, while input sanitization involves removing or encoding potentially dangerous characters.

2. Output Encoding:

All user-generated content that’s displayed on a web page should be properly encoded before being rendered. This prevents browsers from interpreting malicious code as executable content.

3. Content Security Policy (CSP):

CSP is an HTTP header that helps mitigate XSS attacks by specifying which sources of content are considered safe to load on a web page. This can prevent inline scripts and restrict the loading of external scripts to trusted domains.

4. Escape User Inputs:

Escape characters that might be interpreted as code when rendering user-generated content. This ensures that even if malicious code is injected, it’s treated as plain text and not executed.

5. Regular Security Audits:

Regularly audit and scan web applications for vulnerabilities, including XSS. Automated tools and manual code reviews can help identify and remediate potential issues.

Bypassing an Imperva WAF and obtaining XSS

Bug bounty programs and bug hunting are gaining more popularity each year. One of the old and popular vulnerabilities is XSS, specifically reflected XSS. Finding a reflected XSS is quite easy and doesn’t require significant effort to prepare the right payload and trigger a simple alert box if the server doesn’t filter user input. To prevent reflected XSS, developers use various forms of protection, whether it’s input sanitization or using a different WAF (Web Application Firewalls).

Today, we’ll discuss a technique to bypass an Imperva WAF. I will describe in detail how I managed to bypass Imperva’s protection and obtain a reflected XSS on a private bug bounty program.

Note: I will not disclose the actual domain where this type of XSS was found. Instead, throughout this article, I will refer to this domain as redacted.com.

Typically, before commencing web testing, bug hunters engage in information gathering and attempt to understand the functionality of the website. This is exactly what I started doing. The website itself returned the following response:

Reference #30.9f861402.1691918727.ef5e929

I found this response intriguing, and I began brute-forcing directories and files. After some time, I discovered a registration form on the website:

https://REDACTED.COM/REDACTED/account/registration/registration.jsp?redirectURL=/REDACTED/cart/cart.jsp

After a series of manipulations with this endpoint, it became evident that the values of the redirectURL parameter were reflected in the response. This led me to the idea of testing for reflected XSS.

Usually, when testing for reflected XSS, the goal is to identify where in the response the reflection occurs. It turned out that the reflection was happening within an HTML input tag, specifically in the value attribute:

<input name=”redirect” type=”redirect” type=”hidden” value=”/REDACTED/cart/cart.jsp”>

To confirm this, I sent a simple string xssHere to recheck the reflection. In the response, I received the following:

Since the reflection was occurring within the input tag’s attribute, I needed to break out of the attribute and add an event handler with an alert to trigger a popup without user interaction. The payload used was ” autofocus /onfocus=”alert(1)

But Imperva blocked this request. The next idea was to break out of both the attribute and the tag and introduce a new HTML element with an alert box, which also resulted in the request being blocked. Following this, I attempted to identify any HTML elements that were blocked through fuzzing, but unfortunately, all elements were being blocked by the WAF. The characters < and > were not blocked or filtered by the firewall, but requests like <any character were blocked.

To overcome this limitation, I tried URL-encoding characters after the < symbol, which initially didn’t work. However, this didn’t discourage me. I needed to think outside the box, and the idea of sending a request with invalid URL encoding came to mind.

After several manipulations, it turned out that if I sent an incorrect URL encoding, some characters were being converted. For instance, %5K was being converted to the symbol `P`, which opened up the possibility of crafting a new XSS payload.

I assembled the following payload:

%3C%5K/onpointerenter=alert(1)>

This payload, in the response, became:

<P/onpointerenter=alert(1)>

The final payload was:

%22%3EEnter_Mouse_Pointer_Here_to_get_XSS%3C%5K/onpointerenter=alert(location)%3E%3!–

Upon hovering the mouse pointer over the text Enter_Mouse_Pointer_Here_to_get_XSS, I successfully triggered the working XSS.

Conclusion

A Web Application Firewall (WAF) can be an effective tool in mitigating Cross-Site Scripting (XSS) attacks, but it should not be relied upon as the sole line of defense. However, WAFs may not catch every possible XSS attack, especially if an attacker uses a new or highly obfuscated technique. Some attackers may find ways to bypass the rules of a WAF, leading to potential vulnerabilities. While a WAF can be a valuable component in your security posture against XSS attacks, it should be used in conjunction with other security best practices. Adopting a comprehensive approach that includes secure coding practices, regular security testing, and user awareness training will offer a more robust defense against XSS and other web application threats.

Subscribe to Bright newsletter!