I'm trying to protect my code from XSS. I used a tool to identify risks and it alerted the following code part as a possible injection case.
var urlParams = new URLSearchParams(window.location.search); var param = urlParams.get('param'); var newUrl = "/" + param + "/goto"; document.write("<a href="+newUrl+">Link</a>");
I played a little bit around with some payloads but I was not able to break out and inject any code which is executed*. I wonder if this was a false positive or did I just missed a payload which executes code?
Also, in the course of this I have changed my code a little to
var param = window.location.search.split('param=');
I noticed that in the latter case the parameter is url-encoded, whereas this is not the case in the first example.
Does this happen with the split() method? I want to understand the differences.
Example with ?param="; alert(1);
First case: console.log(param) prints "; alert(1);
Second case: console.log(param) prints %22;%20alert(1);
*Update: I was able to find two payloads that work:
But why doesn't they work for window.location.search.split('param=')? It is save to just use this approach instead of the first one or are there possible payloads to bypass, too?