The Setup

It was just another day in the bug bounty trenches. I'd pulled up a new program on my list and started doing what I do best: poking around where I probably shouldn't be. The target? A karting/racing site called kartingbenelux.com.

Before I clicked a single link, I did what every good hunter does: I defined my territory. I opened my notes and wrote down the scope:

*.kartingbenelux.com

Everything under that wildcard was fair game. The main domain, any subdomains, all of it. Time to get to work.

The Reconnaissance Dance

I fired up my usual arsenal of tools while simultaneously clicking through the site like a curious user. This is the ballet of bug hunting — automated scanning in the background, manual exploration in the foreground, both feeding each other information.

My toolkit:

  • subfinder - hunting for hidden subdomains
  • assetfinder - more subdomain discovery
  • feroxbuster - directory brute-forcing to find hidden pages
  • My eyes and a browser — never underestimate manual testing

While the tools did their thing in the terminal, I started exploring the obvious entry points. Login page? Check. Registration form? Check. Both at /login.php and /register.php.

And that's when I saw it.

The Tiny Detail That Changed Everything

As I navigated to the login page, I noticed something in the URL that made me pause:

https://kartingbenelux.com/login.php?lang=en

There it was. The lang parameter. Sitting there innocently, controlling which language the page displayed. Most developers would look at this and think "it's just a language selector, what's the harm?"

But I've been doing this long enough to know: the parameters developers think are "safe" are often the most dangerous.

That little lang=en stuck in my head like a splinter. I made a mental note to come back to it.

What the Recon Revealed

My tools started spitting out results. A couple of subdomains popped up. Various assets and image files appeared in the feroxbuster output. Nothing that screamed "vulnerability" at first glance.

Then I noticed something interesting: profile.php was showing a maintenance page.

Curious, I thought. Someone probably found something there already and the team patched it. Good for them — responsible disclosure working as intended.

But feroxbuster kept churning, revealing a mountain of files: images, CSS, JavaScript libraries, the usual web application detritus. I scanned through them all, but nothing jumped out.

Except… that lang parameter kept whispering to me from the back of my mind.

Going on the Offensive

Intuition is a funny thing in bug bounty hunting. Sometimes you just feel that something is off. That lang parameter felt off.

I decided to stop being polite and start being aggressive. Time to throw some XSS payloads at it.

I fired up XSSer, a tool I trust for automating XSS detection at a basic level, and pointed it directly at my suspect:

xsser -u "https://Kartingbenelux.com/login.php?lang=XSS"
The tool started its work, injecting various payloads and watching how the application responded. And then... bingo.
The output showed that my payloads were appearing in the page source—not once, but **in multiple places**. The application was taking my input and echoing it back into the HTML without proper sanitization or encoding.
This was it. This was the vulnerability.
## Confirming the Kill
Tools can lie. False positives happen. So I needed to confirm this manually, the old-fashioned way.
I opened the page in my browser and hit `View Source`, then `Ctrl+F` to search for my payload hash. There they were—multiple instances of my injected content sitting right there in the raw HTML, ready to execute.
Time to craft a proof-of-concept.
## The Proof of Concept
For bug bounty reports, you want your PoC to be **clean, harmless, and undeniable**. No cookie stealing, no credential harvesting, no malicious redirects. Just something that proves the vulnerability exists without causing any damage.
I crafted a simple payload that would inject a large red H1 tag with the word "HACKED":
```
<h1 style="color:red;font-size:50px;">HACKED</h1>

I injected it through the lang parameter and loaded the page.

The result?

The page rendered my injected HTML element perfectly. A giant red "HACKED" header appeared on the login page, sitting there like a neon sign screaming "THIS IS VULNERABLE."

None
HTML Injection PoC

You could also see some mangled text and visual artifacts scattered around the page — collateral damage from breaking out of the HTML context. These artifacts are common with XSS when your payload escapes its intended boundaries and disrupts the surrounding markup.

But the core issue was clear: arbitrary HTML and JavaScript could be injected through the lang parameter.

This was a critical XSS vulnerability.

The Report and Responsible Disclosure

I immediately documented everything:

  • The vulnerable parameter
  • The injection point
  • Step-by-step reproduction
  • Screenshots and screen recordings
  • A clean, harmless PoC

Then I submitted it to the program.

This is the part that matters most. Responsible disclosure. No public tweets, no blog posts, no showboating until the team has had time to fix the issue and confirm it's safe to share.

The team responded quickly, patched the vulnerability, and gave me the green light to share the findings publicly. That's how it should work — collaboration, not exploitation.

Lessons from the Trenches

This hunt reinforced a few critical lessons:

1. Small parameters can hide big vulnerabilities

The lang parameter seemed innocent—just a way to switch between English and Dutch. But developers often make the mistake of thinking "it's just a language code, it's safe." They skip sanitization, they skip encoding, and suddenly you have XSS.

2. Trust your instincts

When something feels off, investigate it. That nagging feeling about the lang parameter turned out to be right. Experience teaches you to recognize these patterns.

3. Test every context

Input can appear in HTML text nodes, attributes, JavaScript blocks, URL contexts — each requires different escaping. Always check where your payload ends up and how it's being rendered.

4. Responsible disclosure is non-negotiable

Finding vulnerabilities is only half the job. Reporting them properly, giving teams time to fix them, and helping make the web safer — that's what separates hunters from hackers.

The Aftermath

Another critical vulnerability found, another application made more secure. The karting community can race in peace knowing their login page isn't serving XSS to unsuspecting users.

And me? I'm already on to the next target, looking for the next tiny parameter that everyone else thinks is harmless.

Because in this game, it's always the little things that bring down the house.

Got questions? Want to talk bug bounty? Hit me up on Discord

Remember: Everything shown here was responsibly disclosed. The team patched the issues before this went public. Always get permission before testing, and always disclose responsibly.

None
Shoutout to the amazing team for the quick remediation!
None

Stay curious. Stay ethical. Happy hunting.