Securing an AngularJS Web Application

AngularJS Security

Cybersecurity is a Game of Thrones. There is a constant struggle between the various actors to gain the upper hand. We at Osprey Security are no exception. The Osprey Risk Intelligence and Compliance product manages all aspects of an organization’s Cybersecurity needs relating to their Governance, Risk, and Compliance items. For this product, we chose AngularJS to build and deploy our front end web application. The front end is what the users see first and interact with directly, and that’s why it has an important role in the application security. It is the bridge between the user and the data, a friendly way of interaction with data.

There are numerous frameworks out there to implement an appealing user interface, but the ultimate choice depends on our functional and security needs and what and how we want to build. We want to ensure that we take into account, all the features and capabilities that are on offer esp. as it relates to the Risk Intelligence and Compliance product for example.

AngularJS: a front-end framework

We chose AngularJS as our framework for a variety of reasons. To give a brief overview, an Angular application typically communicates with a server to retrieve the data and then present it to the user. The communication could be via RESTful API or a simple web service.

To mitigate most of the common attacks, AngularJS assists in writing code in a way that: is secure by default and makes auditing for security vulnerabilities such as XSS, clickjacking, etc. a lot easier.

AngularJS provides security features such as:

  • Strict Contextual Escaping:  A mode in which AngularJS requires bindings in certain contexts to require a value that is marked as safe to use for that context, otherwise, will not render content that is not marked as safe by $sce.
  • Cross Site Request Forgery (XSRF/CSRF) and JSON Hijacking Protection: Angular comes pre-configured with strategies that address these issues.
  • Local Caches.

But some these features do not stand alone, we need to configure our back-end to make them work and reduce the risk of affecting our server and data.

Sending a bad JSON from or to the backend and handling it in the UI, adding headers in every request are some of the approaches to consider, turning the development of the front-end and backend more complex and a little complex.

Minification

In addition to the security features that are built-in in the frameworks, we apply other methods to make our code more secure. Minifying the JS and CSS files is not only about reducing the size of the required files to be transferred, but also to provide obfuscation to the files, especially to the JS files.

Obfuscation is the act of making the code hard to understand, prevent tampering, and deter reverse engineering without changing the code’s functionality.

Obfuscation does not guarantee 100% protection since the code could be reversed but at least can make reading, writing and reverse-engineering a program difficult and time-consuming and could deter most threat actors except the most advanced or persistent attackers.

If we are using grunt task uglify to minify with default options, we will face an error when we try to run our application. The cause is the name replacing of the angular modules done by the task. To avoid this bug, we need to disable the mangle option in the grunt file.

Let’s see an example of magnification using grunt task uglify leaving the mangle name option set as true:

$scope.login = function (credentials) {

        authService.login(credentials)

            .then(function(currentUser) {

                setUser(currentUser);

            },

            function() {

                $scope.loginAlert = true;

            });

    };

Result:

a.login=function(b){c.login(b).then(function(a){d(a)},function(){a.loginAlert=!0})}

Obfuscation Task

Looking for a proper obfuscation task, one of our favorite grunt plug-ins is called js-obfuscator, which obfuscates JS files via javascriptobfuscator.com.

After modifying the replaceNames option in the Grunt file, to avoid breaking the code for AngularJS module names, we run the same code above to get:

Result:

$scope[_0x3b9e[18]]=function(credentials){authService[_0x3b9e[18]](credentials)[_0x3b9e[19]](function(currentUser){setUser(currentUser)},function(){$scope[_0x3b9e[3]]=true})}

Both of these tasks help us to accomplish our goal to make the code hard to read, and to bring extra protection to our application. It couldn’t be completely possible to hide but at least is our first stand in the war to keep our products safe.

Latest posts by Favre Estrada (see all)


Leave a Reply

Your email address will not be published / Required fields are marked *