This blog covers Cross-Site Scripting (XSS) vulnerability from a different perspective. Generally, XSS is when the application takes user supplied JavaScript and displays it without escaping/encoding. In this blog, we will see how can XSS be exploited even if the application properly escapes/encodes the user inputted JavaScript using different methods. Exploiting XSS in this way can be as drastic as exploiting XSS in the regular way. Using this, an attacker can carry out attacks against the application users such as stealing cookies, creating a Trojan login. This is a regular XSS i.e. reflected XSS, but there are other types of XSS such as Stored and DOM based XSS.
The ever growing need of giving a rich user experience to website visitors have made the need for browsers to include cross origin resources. Sometimes these resources can be data, an iframe, an image or JavaScript.
A website http://example.com can have the following cross origin resources:
They enhance the performance of website as they are cached by the browser from the CDN.
Referring the following scripts will improve performance: <script src=”https://code.jquery.com/jquery-1.8.1.min.js”></script> because multiple sites use the same and the browser has to load it just once from the CDN and after that each time it is referenced, it is served from the browser cache.
If instead of the above, a website refers scripts internally. That is, downloads the jquery-1.8.1.min.js file and serves it from its own root directory like <script src =”http://example.com/jquery-1.8.1.min.js”></script> then it will cause browsers to download load scripts from the internet instead of using it from the browsers cache that is downloaded from CDN as a result of which the performance is affected.
We need external scripts because they allow developers to write less code and let them make DOM manipulations easy.
The following is a jquery’s single line of code to change background colour:
$ (‘body’) .css (‘background’, ‘#ccc’);
In JavaScript, the code to perform the same functionality is:
Function changeBachground(color) {
Document.body.style.background = color;
}
Onload=”changeBackground (‘red’);”
So, 1 line of code in JQuery is equivalent to 4 lines of code in JavaScript when it comes to changing background colour.
Loading scripts from third parties cause security vulnerabilities because the provider has complete control over the content served on the web page. A malicious website can serve malicious JS to a victim site thus doing a Cross Site Scripting attack. Research has leaded us to find the following types of mistakes that cause vulnerabilities:
Suppose in a development environment (for testing purpose), a developer references scripts from another web server running on localhost. For example: <script src=”http://127.0.0.1:4545/import.js”></script>
If this code of the web app goes in production then, in this case an attacker can exploit it in the following way:
Suppose in a development environment (for testing purpose), a developer references scripts from another web server running on a private IP address of the intranet. For example: <script src=”http://192.168.0.111/import.js”></script>
If this code of the web app goes in production then, in this case an attacker can exploit it in the following way:
A developer references scripts from a domain on the internet. For example: <script src=”https://securelayer7.net/import.js”></script>
But due to some reason, in future, this domain expires. Then, in this case an attacker can exploit it in the following way:
A script is referenced from an IP address instead of domain name. This sounds good as long as the IP address is static. For example: <script src=”https:// 184.75.249.44/import.js”></script>
But if the IP address is subject to change, then, in this case an attacker can exploit it in the following way:
A script is referenced from correct domain but with some typing mistake. For example: <script src=”https://code.jqueri.com/import.js”></script>
Notice that in above example, the spelling of JQuery contains ‘i’ in the end instead if ‘y’. In this case, an attacker can exploit it in the following way:
A script is referenced from a server that serves content over HTTP and NOT in HTTPS. For example: <script src=”http://example.com/import.js”></script>
Notice that the domain name is correct without any spelling mistake. In this case, an attacker can exploit it in the following way:
Use of Sub-resource Integrity feature of browsers:
The Subresource Integrity feature enables to mitigate the risk of these attacks, by ensuring that the files Web application fetches (from a CDN or anywhere) have been delivered without a third-party having injected any additional content into those files — and without any other changes of any kind at all having been made to those files. It is done by using the Subresource Integrity feature by specifying a base64-encoded cryptographic hash of a resource the web application is telling the browser to fetch, in the value of the integrity attribute of any <script> or <link> element. For example:
You can use the following <script> element to tell a browser that before executing the https://securelayer7.net/import.js script, the browser must first compare the script to the expected hash, and verify that there’s a match.
<script src=”https://securelayer7.net/import.js“ integrity=”sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC” crossorigin=”anonymous”></script>
When a browser encounters a <script> or <link> element with an integrity attribute, before executing the script or before applying any stylesheet specified by the <link> element, the browser must first compare the script or stylesheet to the expected hash given in the integrity value.
As of now, it is supported by Mozilla Firefox, Google Chrome and Safari.
Apart from this following measure should be taken to secure your JS imports: