Okay so today I was solving an XSS lab, and at first it was honestly confusing But after struggling a bit, I finally figured it out. Let me walk you through it.

Step 1: Understanding the code

I checked the page source and found this script:

function tracking(search, hash) {
    document.getElementById('tracker').href = search;
    document.getElementById(hash).click();
}
var urlParams = new URLSearchParams(window.location.search);
var searchTerm = decodeURI(urlParams.get('search'));
var hashed = window.location.hash.slice(1);
if (searchTerm != 'null') {
    tracking(searchTerm, hashed);
}

There was also a hidden link in the HTML:

<a id="tracker" href="javascript:alert(1)" hidden></a>

Step 2: What the code is doing

After reading it carefully, here's what's happening:

  • ?search=... → sets the href of the link
  • #... → selects an element by ID and clicks it

So basically:

  1. It takes my input and sets it as a link destination
  2. Then it clicks an element based on the hash

Step 3: First attempts (failed)

I tried:

?search=javascript:alert(1)

Nothing happened.

Then I realized: The code also needs a hash, otherwise nothing gets clicked

So I tried:

?search=javascript:alert(1)#tracker

Still nothing… that confused me.

Step 4: Testing if code works

To debug, I tried:

?search=TEST#tracker

Then in console:

document.getElementById('tracker').href
None

It showed "TEST" → so the code is working.

Then I manually triggered:

document.getElementById('tracker').click()

Still no alert.

So the issue wasn't the logic — it was the payload.

Step 5: Understanding the problem

After some research, I realized:

  • Browsers sometimes block javascript: URLs when set dynamically
  • That's why javascript:alert(1) didn't execute

But normal URLs worked:

?search=https://google.com#tracker

This redirected successfully

So the functionality was correct — only the payload behavior was tricky.

Step 6: The important realization

I noticed something very important:

When I typed the payload in the input field, the # became:

%23

So the URL looked like:

?search=javascript:alert(1)%23tracker

And that breaks everything because:

  • %23 is just text
  • It is NOT treated as a real hash

So: window.location.hash becomes empty No element gets clicked No XSS

Step 7: The correct approach

When I typed the payload directly in the URL bar:

?search=javascript:alert(1)#tracker

Now:

  • search = javascript:alert(1)
  • hash = tracker

So:

  1. The link's href becomes javascript:alert(1)
  2. The script clicks the element with id tracker
  3. The JavaScript executes
None
None

XSS triggered

Step 8: Why the hash is critical

This line is the key:

document.getElementById(hash).click();

If there is no hash:

  • hash = ""
  • No element found
  • No click
  • No execution

If there is a hash:

  • It finds the element
  • Click happens
  • Payload executes

Step 9: What I learned

None

Final Payload

?search=javascript:alert(1)#tracker

Important: Type it directly in the URL bar

Big Takeaway

Whenever you see:

  • window.location.search → controls input
  • window.location.hash → controls behavior

Both are user-controlled inputs

Also:

The way you deliver the payload (URL vs input field) can completely change the result.

Alright, that's it for this today. See you in the next one