Prevent XSS in Vue.js using Google Caja
XSS in Vue.js
Cross site scripting is a major problem across all the websites and must be prevented in order to make your website safe. Cross Site Scripting or XSS is when someone injects a malicious HTML/JS code which is executed by the browser and defaces your website. This can happen in ways which we cannot imagine and requires prevention from both Frontend and Backend. Let’s see some ways in which this happens.
When the data from the browser is sent to the server, at times people do put in some JavaScript code or some malicious code into the system. If the system does not parse these text data and Sanitize it out, the server stores it out and when the data loads onto the browser it defaces the site. There are injections which affect both the server side as well as the client side. In this particular article, we will see how can we prevent people from injecting these scripts into our sites through the text input.
Vue.js Vulnerability due to v-html directive
XSS in Vue.js can be easily achieved by injecting HTML code in places where the data sanitization is not in effect and moreover when the data render onto the screen the data must undergo sanitization otherwise it leads to defacing the site. Now let’s have a look at few samples that can cause the site to a potential problem if not sanitized properly.
We will be referring the last article of Vue.js where we deal with the directive v-html in order to render Raw HTML data onto a div. We will use fiddle to run some samples of malicious HTML code and then run it onto the JSFiddle.
- A simple example while we inject events into the Website can be as follows:-
- <a onmouseover=alert(document.cookie)>Try to Click ME!!!</a>
- On entering this data on our editor that we build previously, we find that the DOM renders the data on the <div> , now just hovering above it the alert pops up as shown in the GIF below. Alternatively, you can copy paste the above code into the JSFiddle Editor to see the result below
- XSS, event injection using link
- Alternatively, we can deal with images and make an injection using image tag as well. This can lead to injecting some browser based events using the image tag. This can be triggered on the load of the page. So let’s see the script.
- <img src=”http://bit.ly/2eOLqwr" onload=alert(“HACKED”)>
- Due to this, you can see that the Page loads the image and on the Load completed this script is executed. You can have complex code that someone can inject into the system. Now let’s see it in Action below. Or you can copy paste the above code in the JSFiddle.
- XSS in Vue.js, caused due to onload in image tags
These are some of the ways in which you can inject scripts onto the page. The samples as well indicate how these work in a simple example where we have created a basic HTML Editor using Vue.js.
Google Caja with Computed Properties for preventing XSS
XSS Can be easily prevented using Google Caja when used along side the Computed Properties. Computed properties along with Google Caja can work to get the HTML/JS/CSS sanitized. So in order to achieve this, we can go ahead and just modify our previous editor a bit. The new Vue.js Code will look as follows
NOTE: Google Caja is safety tool for the Sanitization of the input values from the Frontend. This is from Google and is pretty effective tool. It has various advance options that can help in order to implement a complicated Sanitation Rules for any input data.
var app = new Vue({
el: '#app',
data: {
text: ''
},
computed: {
sanitizeText: function() {
return html_sanitize(this.text)
}
}
});
With this code in place, you can see the sanitizeText is a computed value that directly is being calculated from the text value that is being entered by a user in the Textarea. So the HTML template will look like below
<div class="container" id="app">
<h3>
Sample HTML Editor
</h3>
<div class="row">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Editor</h3>
</div>
<div class="panel-body">
<textarea id="editor" v-model="text"></textarea>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">HTML Output</h3>
</div>
<div class="panel-body">
<div class="outputPanel" v-html="sanitizeText"></div>
</div>
</div>
</div>
</div>
</div>
Just for just showing you guys how it behaves you can have a look at the GIF below which shows how the outputs are being extracted when Caja is being used. We have illustrated how the entire anchor tag looks like in the Chrome Debugger. As you inspect the computed value, you will understand that how Caja parsed the value in order to get the sanitized value.
Google Caja for Sanitization of XSS
Conclusion
XSS or Cross Site Scripting can be prevented easily by utilizing some framework that helps to sanitize the data that is being inputted by any user. This as well leads to protection of the website from either perspective, Frontend, and Backend as well. We can very well avoid XSS by using Google Caja and there are various advanced options with Google Caja which we can use to further protect the site.We will also like to hear from you guys regarding other measures that you guys might be taking in order to prevent the site from Cross Site Scripting while using Vue.js.
You can find all the other Vue.js Tutorials out here.
Originally published at The Web Juice.