From Zero to ,500: How a Single Reflected XSS Payload Unlocked My First Bug Bounty + Video

Listen to this Post

Featured Image

Introduction:

Cross-Site Scripting (XSS) remains one of the most prevalent and dangerous web application vulnerabilities, classified as CWE-79 and consistently ranked among the OWASP Top 10. Reflected XSS occurs when user-supplied input is inadequately sanitized and immediately reflected back in the server’s response, allowing malicious JavaScript to execute in a victim’s browser. For bug bounty hunters, mastering XSS discovery and exploitation is essential—not only because it transforms common flaws into high-impact opportunities but also because it remains the most frequently reported bug on platforms like YesWeHack and HackerOne. This article walks through the complete journey of discovering, testing, and responsibly disclosing a reflected XSS vulnerability—from failed payloads to a working exploit that earned a $2,500 bounty.

Learning Objectives:

  • Understand the complete methodology for discovering reflected XSS vulnerabilities in modern web applications
  • Master payload crafting techniques for different JavaScript and HTML contexts
  • Learn WAF bypass strategies and filter evasion using encoding, polyglots, and alternative tags
  • Develop skills in writing professional bug bounty reports with clear proof-of-concept steps
  • Implement effective XSS prevention measures including CSP, output encoding, and input sanitization

You Should Know:

1. Reconnaissance and Attack Surface Mapping

The journey to discovering a reflected XSS vulnerability begins long before any payload is injected. Successful bug bounty hunters invest significant time in mapping the target’s attack surface through systematic reconnaissance.

Subdomain Enumeration: Start by discovering all subdomains within the program’s scope. Tools like Subfinder and assetfinder are essential for this phase:

 Subdomain enumeration with Subfinder
subfinder -d example.com -all > subdomains.txt

Additional enumeration with assetfinder
assetfinder example.com -subs-only | grep example.com$ >> subdomains.txt

Remove duplicates
cat subdomains.txt | sort -u > subdomains-unique.txt

Live Subdomain Discovery: Not all enumerated subdomains are active. Use httpx to filter only live hosts:

cat subdomains-unique.txt | httpx -o live-subdomains.txt

Parameter Discovery: Once you have live targets, the next step is discovering hidden parameters that might reflect user input. Tools like Arjun, ex-param, and DalFox automate this process by fuzzing for parameters that aren’t visible in standard web crawling:

 Parameter discovery with Arjun
arjun -u https://example.com/endpoint -o parameters.txt

Reflected parameter detection with ex-param
ex-param -u https://example.com/endpoint -o reflected-params.txt

The goal is to identify every controllable input point—URL parameters, headers, cookies, and form fields—that might be reflected in the response.

2. Contextual Payload Crafting and Testing

Once you’ve identified a parameter that reflects user input, the critical next step is understanding where and how that input is reflected. This determines which payloads will work.

Identifying the Reflection Context: As demonstrated in a real-world $2,500 bounty discovery, a parameter reflecting into a JavaScript context requires completely different payloads than one reflecting into HTML:

// JavaScript context reflection - the input ends up inside a variable
var referralCode = "user-input-here";

// Payload to break out of the string context
";alert(1);//

// Resulting code after injection
var referralCode = "";alert(1);//";

HTML Context Testing: For parameters reflected directly into HTML, basic script tags may work:

<script>alert('XSS')</script>

Input Field Context: When reflection occurs inside an input tag’s value attribute, use autofocus with onfocus event handlers:

" style="visibility:visible" onfocus="alert(1)" autofocus="

Template Literal Context: Modern JavaScript applications sometimes reflect input into template literals. PortSwigger labs demonstrate escaping backticks and injecting expressions:

// If reflection is inside a template literal: `${user-input}`
// Payload to break out and execute
${alert(1)}

Burp Suite Workflow: The most efficient way to test payloads is using Burp Suite’s Repeater. Intercept the request, send it to Repeater, modify the parameter value, and analyze the response. The Burp Decoder helps with encoding payloads for different contexts.

3. WAF Bypass and Filter Evasion Techniques

Modern web applications often employ Web Application Firewalls (WAFs) and input filters that block common XSS payloads. Successful exploitation requires understanding these defenses and crafting payloads that evade them.

Case-Insensitive Bypass: JavaScript is case-insensitive, so mixing uppercase and lowercase can bypass simple filters:

<ScRipt>alert(1)</ScRipt>

Alternative Tags and Event Handlers: When `