Below are a short set of10 AngularJS security fundamentals best practices that I'll cover in this blog post. See original link for more in-depth details and code snippets.
Or you could just download this lovely PDF and pin it in your wall to never lose sight of these AngularJS Security Fundamentals:
Why am I even talking about AngularJS?
Angular v1.x makes up for, approximately,30% of all Angular version downloads and just over 2 million downloads in July 2019.
1. The “Angular way” safeguards you from XSS
AngularJS by default applies automatic output encoding and input sanitization that is context-aware for any data values that are pushed on to the DOM. As long as you are doing things the “Angular” way you benefit from this safeguard.
Using Angular’s ng-bind
Angular’s ng-bind directive allows you to bind value to an HTML’s element value from the one that was set in Angular’s code, such as the controller.
<div ng-controller="AboutController as about"> <h1>About</h1> <p> Signed by: </p> <div ng-bind="about.signature"></div></div>
Using Angular curly braces
Another way to bind data value into their HTML elements values is by using Angular’s convention of double curly braces. Both ngBind‘s directive and curly braces’ notation is the same, with some subtle differences regarding the UX.
Here’s an example of how Angular encodes malicious data when using curly braces, starting off with adding a description value to the view:
<div ng-controller="AboutController as about"> <h1>About</h1> <p> {{ about.description }} </p> <p> Signed by: </p> <div ng-bind="about.signature"></div></div>
2. Avoid using Angular DOM-related input injection
Key takeaway: Avoid using Angular DOM-related input injection which may introduce vulnerabilities.
- In Angular 1.2 and prior avoid using the ng-bind-html-unsafe directive
- In Angular 1.2 and later avoid blindly trusting user input with Strict Contextual Escaping collection of methods such as $sce.trustAsHtml(value)
Earlier AngularJS versions such as 1.2 and prior had anng-bind-html-unsafe
directive which allowed to insert HTML data into the DOM and create new elements. Some practices for using this was to create DOM elements straight from data input and then filter certain strings in them, like remove links and others.
Using this approach to black list data is error-prone and not always safe due to new attack vectors and methodologies that are discovered over time and require maintaining such black list.
The AngularJS 1.2 release has deprecated theng-bind-html-unsafe
directive and introduced Strict Contextual Encoding (SCE) instead. SCE enables escaping and sanitization data based on a context but not on a specific HTML element’s data.
That said, escape hatches exist that allow you forgo the encoding and assume that the data provided is safe to use. Such actions are made possible with Angular’s methods$sce.trustAsHtml()
and$sce.trustAs(type, value)
.
3. Avoid dynamically loading Angular templates from untrusted sources
Angular code makes use of Angular templates all the time. These HTML templates look like this:
<div> Hello, {{ name }}</div>
This introduces the risk of insecurely loading templates over untrusted domains that are beyond the control and trust of the web application. Moreover, developers should take further note of accessing the templates over secure protocols such as up-to-date versions of TLS to mitigate Man-In-The-Middle attacks.
An example of how an Angular template is loaded dynamically over the network:
angular.module(‘myModule’) .component(‘myComponent’, { templateUrl: ‘/path/to/template.html’, controller: function() {} });
4. AngularJS open redirect vulnerabilities
The browser-native APIs provide page navigation capabilities, such as$window.location
. Angular abstracts the navigation handling with the$location
service provider and provides methods such as$location.url()
,$location.path()
and$location.hash()
, as well as others, to access the current navigation URL and synchronises it, as required.
You possibly have Angular code that performs navigation based on URL query parameters or other URL related data.
However, since the URL address is in the control of the user browsing the web application, that means a user can set the hash to valid JavaScript code — for example Best practices to mitigate server-side Angular code injection: More about angular.element from Angular’s official documentation onhttps://docs.angularjs.org/api/ng/function/angular.element. Key takeaway: Avoid using Angular’s angular.element() jQuery-compatible API to manipulate the DOM as this leads to potential Cross-site Scripting vulnerabilities due to directly creating HTML elements on the DOM. Linters are common in the world of JavaScript development and often developers make use of a popular project like ESLint along with plugins that extend it. The Key takeaway: Use static code analysis tools to automate finding insecure code and alerting developers when this happens, early in the process of development. Security linters that are part of AngularJS security fundamentals: It’s highly likely that you are using open source packages on top of the Angular core and its extended components in order to build your web application. In fact, the AngularJS project itself has vulnerabilities. According to a study on JavaScript Frameworks Security by Snyk, AngularJS has over 20 security vulnerabilities across the Angular 1.x version branch. Moreover, there the dependencies you use to build your Angular-based web application that possibly have security vulnerabilities too. As the following table shows, some of those vulnerabilities don’t even have an available fix, to date. Looking for an AngularJS security scanner? To stay up to date with security vulnerabilities on your frontend project, use Snyk and connect your GitHub or Bitbucket projects — that way Snyk automatically finds and creates fix pull requests for you. Another quick way to get started is to use the Snyk CLI: When you run a Snyk test, Snyk reports the vulnerabilities found and displays the vulnerable paths so you can track the dependency tree and understand which module introduced a vulnerability. Snyk provides you with actionable remediation advice in order to upgrade to a fixed version through an automated pull request that Snyk opens in your repository. You can also apply a patch that Snyk provides to mitigate the vulnerability if no fix is available. If you’re looking for anything close to an AngularJS security scanner you should start with Snyk as a way to track your open source dependencies, get notified, and fix them as vulnerabilities are discovered. Key takeaway: AngularJS has over 20 vulnerabilities to date and there are Angular components with millions of downloads that are still vulnerable. Angular has a built-in support for CSRF tokens in which it reads cookies of specific naming conventions, such as XSRF-TOKEN, that is sent from the server and appends the value to further HTTP requests being made from the Angular application. The entire CSRF token handling is done within the $http service for AngularJS. For newer Angular versions it is also provided via the HttpClient in the officially supported Key takeaway: Angular has built in support for CSRF token handling on the client-side via its AngularJS has CSP-related built-in controls but when enabled, it has to exclude some functionality — for example, not allowing inline scripts and expressions, due to eval() not being permitted. Yet, this is internally required by AngularJS for some of its features. Recommended reading on CSP is on Mozilla’s website and Angular’s API documentation for the Key takeaway: Implementing a Content Security Policy (CSP) is an important step in providing an additional layer of security, especially one that helps mitigate Cross-site Scripting attacks. -- I am a Developer Advocate atSnyk. This post originally appeared on the Snyk blog, with even more security tips where you can find the full article onAngularJS security fundamentals as well as an easily shareable pdf.https://www.example.com/path/to/this##"5-serverside-angular-code-injection" href="#5-serverside-angular-code-injection"> 5. Server-side Angular code injection
ng-app
directive from an HTML’s document body to specific DOM element context within the page itself.ng-bind
orng-bind-html
to ensure user input is being properly handled with Angular’s support for output encoding and sanitization controls with these Angular directives.ng-non-bindable
to make sure the data is not being treated by Angular as an expression that needs to be evaluated and so mitigating the Angular code injection. 6. Avoid using the Angular .element jQuery-compatible API to manipulate the DOM
7. Use Angular security linters
eslint-plugin-angular
project helps with general Angular coding conventions and guidelines. It also has some rules for security, one of which isno-jquery-angularelement
that disallow wrapping of angular.element objects with jQuery or $. 8. Scan and fix vulnerabilities in Angular third-party components
Scan for vulnerabilities
npm install -g snyksnyk test
9. Built-in CSRF support for Angular applications
@angular/common/http
module. It also provides further configuration of the cookie name for the CSRF token and general behavior via the$http.xsrfCookieName
API and others.$http
service. Use this service instead of rolling your own. 10. Angular’s built-in CSP compatibility
ngCsp
directive.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse