Reflected XSS with AngularJS expression escape and CSP

Objective

Final Payload

<script>
location='https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cinput%20id=x%20ng-focus=$event.composedPath()|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
</script>

Let's URL decode the payload

<script>
location='https://YOUR-LAB-ID.web-security-academy.net/?search=<input id=x ng-focus=$event.composedPath()|orderBy:'(z=alert)(document.cookie)'>#x';
</script>

Reverse Engineering The Payload

Step1: Set the Location

The first step of the payload is to set the location property which is a built-in JavaScript object that represents the URL of the current page, and setting it to a new URL is constructed using a template string that includes the following components:

  • The domain of the lab instance, which is specified as “https://YOUR-LAB-ID.web-security-academy.net/”. Note that “YOUR-LAB-ID” would be replaced with the actual ID of your lab instance.

  • A query string parameter called “search”, which is specified as “?search=”. Also query string parameters are used to pass data to a webpage via the URL.

  • An AngularJS expression that includes an input element with an ID of “x” and a “ng-focus” directive. We will take a closer look at this expression in the next step.

  • A hash character (#) to indicate the start of the fragment identifier, which is used to specify a location within the page. In this case, the fragment identifier is set to “x”.

Examining the ng-focus Directive

On the page below, a simple HTML application is presented to demonstrate how the ‘ng-focus’ directive works. When the user focuses on the input box by clicking on it or pressing the tab key, the JavaScript expression is executed in this particular example.

Step2: AngularJS Expression

The AngularJS expression that is included in the search parameter of the URL is where the paylaod executes its malicious code. The expression is constructed using the following components:

  • An input element with an ID of x. This element will be created on the page when the URL is loaded, and it will trigger the payload when it is focused by the user.

  • A ng-focus directive, which specifies a function to be executed when the input element is focused. The function is constructed using the pipe(|) operator to chain together two AngularJS functions: composedPath() and orderBy().

  • The composedPath() function is called with the event object passed as an argument. This function returns an array of all the elements that the event passed through on its way to target element (in this case the x input element).

  • The orderBy() function is called with the two arguments: the array of elements returned by composedPath(), and a value of (z=alert)(document.cookie).

  • The first argument passed to orderBy() tells the function which property to use as the sorting key. In this case array contains elements, hence it is treated as an array of values rather than array of objects. Therefore, the first argument can be any value. However, it is necessary to include the argument to avoid a syntax error.

  • The second argument passed to orderBy() is the expression to be used to determine the sorting order. In this case, the expression is (z=alert)(document.cookie). This expression first assings the alert function to a variable called z, and then calls z with document.cookie as an argument. This causes an alert box to be displayed in the user’s browser that shows the content of the document.cookie property.

Putting Them All Together

  1. After landing the lab instance go to the exloit server.

  2. Copy the final payload and modify it with your lab-id. Then paste it to the body field and click store.

  3. Finally click Deliver exploit to victim , then the lab should have been solved.