Reflected XSS with AngularJS Sandbox Escape without Strings

Objective

  • After the landing page is loaded set a canary and inject into the search field.
  • View the page source and observe that your canary is between the angularJS script.

Remember that you are dealing with angularJS sandbox, that means regular attack vectors are not going to work. For being able to deliver a successfull XSS attack you have to bypass the angularJS sandbox.

Final Payload

Below payload is the final payload in order to bypass the angularJS sandbox.

https://YOUR-LAB-ID.web-security-academy.net/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
  • Modify the payload with your lab-ID and paste the payload into the browser(s) search bar.

    And the lab should have been solved.

Reverse Engineering the Payload

You can copy the above payload and paste it to the search field directly. But if you are wondering how this payload really works and what it does, I suggest you to keep scrolling down.

  1. The payload starts with the expression toString().constructor.prototype.charAt=[].join;. This line of code modifies the behavior of the charAt method of the JavaScript string object. The charAt method is typically used to extract a character at a specified index of a string. By assigning [].join to charAt, the behavior of the charAt method is changed to join all elements of an array into a string, instead of extracting characters from a string.

  2. The : at the end of the line seperates the charAt modification from the rest of the payload.

  3. The next part of the payload is [1]. This creates an array with one element, which is the number 1.

  4. The | symbol is used to apply the orderBy filter to the array.

  5. The orderBy filter is followed by the argument: toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1. This is a JavaScript expression that converts the ASCII codes: (120,61,97,108,101,114,116,40,49,41) into the string x=alert(). This is a malicious JavaScript code that displays an alert message with the value 1.

  6. The =1 at the end of the expression is included to ensure that the expression returns a truth value. In AngularJS, a filter expects a truthy value to be returned from the argument expression, the expression returns the truthy value 1, allowing the orderBy filter to execute the malicious JavaScript code.

  7. The final expression is passed as the argument to the orderBy filter, which sorts the array of elements based on the argument expression. However, since the argument expression is malicious, the orderBy filter will execute the malicious JavaScript code, bypassing the AngularJS Sandbox security feature and allowing an attacker to execute arbitrary code in the AngularJS environment.

  8. The entire payload is included in a URL query parameter which is passed to the vulnerable website. When the website processes the URL, the payload is executed and the malicious JavaScript code is run, bypassing the AngularJS Sandbox security feature and allowing an attacker to perform arbitrary actions on the target website.