This blog talks about the different ways of protecting our web applications based on
AngularJS, from XSS attacks. There are other articles, sources available which talk about either escaping the malicious content like scripts, HTML tags etc. or ignoring few specific tags like img, script etc.
In either of the above solution, we don’t get to see the exact content which was inserted in the db, in short, we manipulate the data content.
For a scenario where we have to display the same content as it was entered by the user then we need a way to disinfect the malicious code & then render it.
Such a scenario will occur where we are allowing users to insert data into db through some API directly or we are allowing the user to enter data from UI without any security gate between the UI and database.
AngularJS itself takes care of not evaluating the HTML tags when putting in expressions like
In this case if the scope variable had some data like :
$rootScope.MalaciousCode= "alert('Aw Snap, Attacked')<img src=''>Usual Content<b>Bold</b>";
It would render just like that.
This applies to ng-bind as well.
You can explicitly trust the content as HTML and binding it with bind-html attribute using $sce service, this is not recommended though.
Let’s take care of the scenario where we have to evaluate the incoming data, any way, like in case of tool-tips.
<div></div>
In this case, even if the data is rendered safe but when it is hovered over it is evaluated
& attack happens.
Solution
For this scenario we either encode the data in client size before passing it to the attribute ‘tool-tip-unsafe’ or as a single point of solution data coming in from server can be HTMLEncoded, with ” encoded, thus what we get is a safe HTML encoded string which if evaluated & trusted as HTML string can be used to render the data as well as showing tool-tips or other usages which may evaluate data.
Data entered by the user:
alert('Aw Snap, Attacked')<img src=''>Usual Content<b>Bold</b>
Encoded data from rest service
alert('Aw Snap, Attacked')<img src=''>Usual Content<b>Bold</b>
Include ngSanitize module library:
Load ngSanitize service as a dependency, this makes sure that bind-html goes through sanitization.
var xssApp = angular.module('xssApp', ['ngSanitize','ui.bootstrap']);
<div></div>
References:
Read more about $sanitize service: https://docs.angularjs.org/api/ngSanitize/service/$sanitize
Related article: https://dzone.com/articles/angularjs-how-handle-xss