Lab: DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded
This lab contains a DOM-based cross-site scripting vulnerability in a AngularJS expression within the search functionality.
AngularJS is a popular JavaScript library, which scans the contents of HTML nodes containing the ng-app
attribute (also known as an AngularJS directive). When a directive is added to the HTML code, you can execute JavaScript expressions within double curly braces. This technique is useful when angle brackets are being encoded.
To solve this lab, perform a cross-site scripting attack that executes an AngularJS expression and calls the alert
function.
Solution
Analyze the Application
-
Open the Lab: Access the lab from the PortSwigger Academy.
-
Inspect the Source Code:
- Use the browser developer tools (e.g.,
Ctrl+Shift+I
in Chrome) to analyze the web page’s source code. - Identify where user input is reflected and how AngularJS expressions are processed.
- Use the browser developer tools (e.g.,
-
Test for AngularJS Binding:
- Enter a simple AngularJS expression, such as
{{7*7}}
, into input fields. - If
49
is rendered on the page, AngularJS is processing the input.
- Enter a simple AngularJS expression, such as
Identify Encoding Restrictions
-
Input Restriction Analysis:
- Test special characters like
<
,>
, and"
to confirm they are HTML-encoded. - For example, entering
<
gets reflected as<
, and"
appears as"
in the HTML source.
- Test special characters like
-
Payload Adjustment:
- Since angle brackets and double quotes are encoded, we need a payload that does not rely on these characters directly.
- AngularJS allows certain constructs that don’t require
<
,>
, or"
.
Crafting the Payload
AngularJS provides alternative syntax that can bypass encoding restrictions. Instead of using double quotes, AngularJS supports single quotes. For example, you can craft a payload using {{constructor.constructor}}
to invoke the Function
constructor.
Payload:
{{constructor.constructor('alert(1)')()}}
Explanation:
constructor.constructor
accesses theFunction
constructor.'alert(1)'
creates a function that triggers a JavaScript alert box.()
executes the function.
Inject and Execute the Payload
-
Locate the input field where your payload can be injected.
-
Insert the payload:
{{constructor.constructor('alert(1)')()}}
-
Submit the input or interact with the page to trigger the execution.
-
If successful, a JavaScript alert box will appear.
Submit the Lab
After successfully stealing the session key or triggering the alert box, the lab will be marked as solved.