XSS Protection with AngularJS

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

{{MalaciousCode}}

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.

problem

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>

Rendering
output

References:
Read more about $sanitize service: https://docs.angularjs.org/api/ngSanitize/service/$sanitize
Related article: https://dzone.com/articles/angularjs-how-handle-xss

Using Native Filters in Angular, Not In The Markup

This post talks about a most common need while working with angularJS, the need to filter data using native filters provided by angular but not in the HTML template i.e. markup.

We might need such a scenario when we are computing/formatting the value to be filtered in some method & returning the value in the markup. It can be a date, a currency calculation (coming from server as x rupees & y paise, to be displayed as x+ y/100 rupees) or something which can be given to the native filter.

For eg: We want to format the time-stamp returned by a method in a date format we need.

We do the same in the markup/template as:

<div> {{myDateValue | date : 'dd/mm/yyyy'}}</div>

But consider a method returning you a time-stamp or a date string which has to converted into a valid date object & then has to formatted.

In such a case we would like to do the filtering in our controller.

For having a native filter to be available in our controller we need $filter service to be injected.

angular.directive('myCustomDirective', function($filter){
  return {
    compile: function(){
            return function(scope){
                  scope.getFormattedDate = function(date, format){
                       return $filter('date').(new Date(date), format);
                  };
           };
    };
  };
});

We can then use the scope method on our markup as:

<div> {{getFormattedDate(myDateValue, 'dd/mm/yyyy')}}</div>

This extends the use-case to the scenario where you have to add/modify the date value before formatting it.

scope.getFormattedDate = function(date, format){
 return $filter('date').(new Date(new Date(date).getDate() + 3), format);
};

Thumb Rule: “For any operation in the data to make it filter ready & if we have to get back to JS code, to apply native filter we need $filter service.”

The useReducer Hook

We have been writing components as functions since our introduction to Functional Components. With the React Hooks being available since version 16.8, there is more power to React which allows developers to think in terms of Functional Programming.

But after writing components in a traditional way of defining them as classes, when you move to components as function, you may feel the lack of statefulness.

The functional components by design were meant to be stateless. But the introduction of React hooks allowed us to controls states of a functional component.

The simplest way to control the state of a functional component is using the useState hook.

Screenshot 2019-07-25 at 9.31.11 PM

Like you had multiple properties of the state in a traditional Class component, you can have as many “useState” hooks in your component.

Usage of multiple such useState hooks will lead to complex & somewhat less maintainable component code when you have state updates based on the values of other state variables.

If you have used Redux, you are missing Reducer already!

Reducer allows you have a cleaner update to the state. You have switch cases & have a very deterministic walkthrough of the code at a glance.

The useReducer hook allows to have a reducer, making all the state changes encapsulated in a function.

Screenshot 2019-07-25 at 9.28.30 PM

This makes a functional component capable of handling states like a traditional component would have done it with the help of redux.

You can further organise this by having a separate file for reducer & the action creators, which will make it even identical to the code organisation of Redux.

Does this call for end of Redux ?
The answer is no.
useReducer is bound to the state changes of a specific component, where as you can control the state management across components through Redux.
Redux gives you an application wide visibility of the state in a managed way which useReducer will not.

Provided that opinion, you can still maintain states across components using a combination of useReducer hook & context API.
Lets learn that next 🙂

Transpilers Are Here To Stay

We have ES6 specification completed and is pending approval & the developers will steadily move toward using next generation JavaScript.
Spec:
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

ES6 next exit

But to keep ourselves up in the race we must start using ES6 features today as just learning & waiting for it to be supported across all major browsers will not help.

A good news that this specification comes up with is that we already have few features available under experimental support given by browsers like Google Chrome & some of them we were using already.

To make the support ready today, we need a tool called as transpiler. A transpiler converts code from one syntax form to another. Thus using a transpiler we can convert code written in JS v6 to JS v5, making us able to start writing code in ES6 syntax using new features without worrying about the browser support.

There are some transpilers already available, here are a few:

One that looks most promising as of date is Babel with detailed documentation & tutorials.

There are many transpilers and CLI tools available but most of them are not complete & are under development.
Addy osmani provides a detailed list here:
https://github.com/addyosmani/es6-tools

Babel allows you convert your JS6 code into JS5 syntax in their try it out editor.
Below is screenshot showing conversion of an example of  rest parameters.

In my current project I am using features like classes & de-structuring, by converting the code using try it out link. A CLI tool can facilitate this in a better way.

In brief, as the transpilers are yet under development & ES6 spec is yet to get approval with ES7 on the way, transpilers are here to stay.
Transpilers will have a long term usage for developers as we can’t expect the browsers to be ready & provide support for all the features immediately.
So start using ES6 today !!! 

References & further read:

Customize select options – Formatting option text

We all must have faced a challenge of formatting select options, as the specification says the content of option can only be plain text.
Specification: http://www.w3.org/TR/html-markup/option.html
Thus we might use jQuery widgets for a custom select.

Recently I faced a challenge working with select/drop-downs that I had to show a tip/help text to the extreme right in an option.  Just for adding few spaces, using a custom select directive or widget didn’t seem to be a good option.

This article talks about making use of angular’s binding mechanism to get a value option with calculated number of spaces added between the option-text & help text.

First thing is to set a limit to the number of characters you can have in the option text, and rest of the logic goes like this:

Add this helper function & a constant to your controller:

const CHAR_LIMIT = 100;
$scope.getComputedText = function(text, help){
var spaces = “”;
var spacesNeeded = CHAR_LIMIT – (text.length + help.length);
for (var idx = 0; idx < spacesNeeded; idx++){
spaces += String.fromCharCode(160);
}
return text + spaces + help;
}

Generate your select mark-up like:

<select>
<option ng-repeat=”currentOption in availableOptions”>
{{getComputedText(currentOption.text, currentOption.helpText)}}
</option>
</select>

PS: Doing this called for writing a post, as adding &nbsp; didn’t work. The option value will show &nbsp; s as it is in drop-down, after adding & nbsp;s dynamically based on text length.

String.fromCharCode(160) does the trick.

HtmlSelectTag1Pic2
Happy Coding. 🙂

Playing videos in SVG

As per latest SVG recommendation by W3C which is v1.2
http://www.w3.org/TR/SVG/

SVG doesn’t have native support for adding videos.
Video should have been loaded either a texture of a shape or there should have been a video element like we have in SVG.

In the recommendation v2 for SVG it is proposed that it should be supported, in the following requirement specifications
http://www.w3.org/Graphics/SVG/WG/wiki/SVG2_Requirements_Input#the_.3Cvideo.3E_element
http://www.w3.org/Graphics/SVG/WG/wiki/SVG2_Requirements_Input#Arbitrary_fill

But we can add HTML content within SVG markup using <foreignObject>.

The foreignobject can either contain an iframe, for example to embed a youtube video we can have:
<svg>
<foreignObject>
<iframe width=’500′ height=’300′ src=’youtube video URL‘ frameborder=”0″>
</foreignObject>
</svg>

or we can have video tag within foreignobject:

<svg>
<foreignObject>
<video src=”video URL” style=”width:300px;      width:500px”>
</foreignObject>
</svg>