Google firing range vs portswigger labs

Hi all,

I’m new here so I hope I’m asking in the right place. I’ll keep it short and simple!

On this lab, we can use the payload in the URL:

But, on Google’s firing range, the same payload gets encoded to:

%3Cimg%20src=1%20onerror=alert(document.domain)%3E

What’s the difference? (I thought modern browsers encoded all tags. Is this a server setting?)

Thanks,

  • Dan

Hi Dan.

Are you referring to this thing Address based DOM XSS?

If that’s the case, you can take a look at the source of the mentioned pages, test it in the console and you can see the difference by yourself.

After doing it myself, I noticed that the google’s one is:

var payload = window.location.search.substr(1);
document.write(payload);

and the portswigger’s one is:

var stores = ["London","Paris","Milan"];
var store = (new URLSearchParams(window.location.search)).get('storeId'); 
document.write('<select name="storeId">');
if(store) {
 document.write('<option selected>'+store+'</option>');
}
for(var i=0;i<stores.length;i++) {
 if(stores[i] === store) {
  continue;
 }
 document.write('<option>'+stores[i]+'</option>');
}
document.write('</select>');

If you run both snippets in the console of the web browser, you will notice that (new URLSearchParams()).get() returns a decoded value of the parameter, which makes sense because its purpose is to parse URL parameters.
In the case of location.search it just returns the raw string as in the address bar (it may not be always the case).

I hope my explanation makes sense.
Best.