Angular security best practices
2020年8月10日
0 分で読めますPreviously, we have shared our AngularJS Security Fundamentals cheatsheet. This time around, we dive straight into the modern Angular security best practices. You can download the Angular Security Best Practices cheat sheet here.
6 Angular security best practices
The “Angular way” safeguards you from XSS
Use innerHTML with caution
Never use templates generated by concatenating user input
Never use native DOM APIs to interact with HTML elements
Avoid template engines on server-side templates
Scan your Angular project for components which introduce security vulnerabilities
1. The “Angular way” safeguards you from XSS
Angular security best practice #1: use interpolation ({{ }}) to safely encode potentially dangerous characters and escape untrusted HTML or CSS expressions within a template expression.
Angular, much like React and Vue.js, takes on a security-by-default approach in the way it handles string interpolation in the browser. By default, all data is treated as unsafe and untrusted, and hence all of these libraries, and other modern view libraries, follow the best practice of performing output encoding by default for any text in an HTML context.
As we described in length in our previous blog post about AngularJS Security best practices, it is strongly recommended to follow the “Angular way” by using its built-in curly braces string interpolation in order to escape any malicious user input that could put your web application at risk and may potentially lead to exposing your web application to Cross-site Scripting (XSS) vulnerabilities.
2. Use innerHTML with caution
Angular security best practice #2: If you must dynamically add HTML to a component, bind its generation to [innerHTML]
. This ensures data will be interpreted as HTML in its context and sanitized, removing all unsafe tags and hence preventing it from executing any malicious cross-site scripting code. Notice that the action of sanitizing is not the same as encoding.
What is the difference between sanitization and output encoding?
In output encoding, strings are replaced with their text representation, which can be mapped to a certain HTML tag. For example, if an input such as script
is parsed, Angular can choose to display that text by encoding the special angle brackets notation, a standard for many other libraries and frameworks implementing security best practices. In order to do so, it performs a mapping of what is known as HTML entities encoding and writes to the DOM the following text: script
. The browser then interprets the context and outputs a script
tag.
We appreciate that, unlike output encoding, the action of sanitization or filtering takes a more proactive approach of detecting unsafe characters and removing them from the text that is then written to the DOM.
Context then becomes a deciding factor of output encoding and sanitization as it has a direct influence on how to properly perform the action.
We can refer to the Angular documentation to learn more about security contexts., In their own words:
Angular defines the following security contexts:
* HTML is used when interpreting a value as HTML, for example, when binding to innerHtml.* Style is used when binding CSS into the style property.* URL is used for URL properties, such as * Resource URL is a URL that will be loaded and executed as code, for example, in .
Note the special treatment of URLs, which are not filtered.
3. Never use templates generated by concatenating user input
Angular security best practice #3: Never concatenate any potentially user provided input as a string to a template.
There should be minimal use-cases—if at all—deriving in the need to concatenate templates rather than properly using string interpolation or the recommended component composition in an Angular application. If you ever come across this bad practice in a codebase, you are encouraged to sanitize or refactor, to all possible extent, the provided input.
Here is an example of what you should watch out for and avoid:
Angular Security best practice: never use templates generated by concatenating user input
Pay special attention at the unconventional string to template concatenation in line 20. potentialUserInput
‘s value may be a malicious expression of unknown or untrusted origin. This is an example of a bad practice and one that you should watch out for.
Following is a more complete picture which you can try in my Angular playground, showing how user input isn’t handled safely if concatenated to the template:
Angular Security best practice in action: never use templates generated by concatenating user input
In this regard, the Angular security guide official recommendation states:
“Never generate template source code by concatenating user input and templates. To prevent these vulnerabilities, use the offline template compiler, also known as template injection.”
- Angular security guide
Angular recommends to use its Ahead of Time compiler to compile templates offline. This helps you entirely avoid the plethora of template injection vulnerabilities:
ng build --aot
ng serve --aot
Please notice that in latest versions of Angular — Angular v9 and higher — compiling with Ivy, ahead of time compilation is set to true by default, preventing template injection:
{
"projects": {
"my-existing-project": {
"architect": {
"build": {
"options": {
...
"aot": true,
}
}
}
}
}
}
4. Never use native DOM APIs to interact with HTML elements
Angular security best practice #4: Never use native DOM APIs to interact with HTML elements on the page.
Avoid direct DOM manipulation and use Angular template mechanisms, and Angular’s own APIs to manipulate the DOM instead. As a general guideline, avoid the following:
node.appendChild();
using the
document
object methods to interact with the pageusing jQuery APIs
There are native Angular APIs that allow the same type of direct DOM manipulation that we’re advising against—for example, the ElementRef API. Angular ElementRef introduces security issues when used to gain access to a direct DOM node and perform manipulations at that point.
This and other interactions outside of the Angular set of APIs could potentially lead to security vulnerabilities.
5. Avoid template engines on server-side templates
Angular security best practice #5: Avoid 3rd party template engines to create or add templates data on Angular server-side rendered applications.
If you’ve been using Node.js to build web applications, you have probably used a template engine such as EJS, Pug, Handlebars, or one of their alternatives at some point in time. They are used to manage server-side rendered templates for the view layer and may include partials or layouts composites, and other sorts of features that help dynamically generate a view.
However, implementing these template engine mechanisms in a configuration of Angular’s server-side rendered application could lead to potential injection of malicious code into a template. That happens because data injected is external to the scope of the Angular API and cannot be sanitized, posing the same risks as template string concatenation
6. Scan your Angular project for components which introduce security vulnerabilities
Angular security best practice #6: Always scan your Angular project open source dependencies and Angular components for security vulnerabilities. Use Snyk platform or CLI for free to find, fix and monitor for security vulnerabilities.
When it comes to using third-party libraries, like Angular and its ecosystem of modules or components, you should keep the following in mind: security vulnerabilities affecting the core Angular library, and security vulnerabilities in the third-party Angular modules you are importing and using in your project.
Using components with known vulnerabilities is actually a documented OWASP Top 10 web security risk that you should be aware of.In fact, the picture below shows a list of Angular modules with known security vulnerabilities, for example, those that would get flagged when you run an npm install
or npm audit
. Indeed, as you see in this picture taken from our JavaScript Frameworks Security report, some of these are winning millions of downloads a year yet have no security fix to this date:
Securing Angular web applications
If you’re using npm audit
this is a great first step and you’re doing a good job already!
However, even if you’re using npm’s audit feature, there are still security concerns you should mitigate:
You might have resolved all security vulnerabilities in the project for now, but what happens when a new vulnerability is discovered for one of those Angular modules? Will you know if it impacts one of your deployed Angular applications to Vercel, Netlify or others?
The other concern is that
npm audit
is only tracking known vulnerabilities that have an official CVE, however, [Snyk tracks over 23 security vulnerabilities for Angular related modules](https://snyk.io/blog/angular-vs-react-security-bakeoff-2019/) where-as npm audit reports none of these.
Snyk solves both of these concerns for you, and it’s free ;-)
How to get started?
Create your free Snyk account and connect your GitHub or Bitbucket frontend projects —that way Snyk automatically finds and creates fix pull requests for you.
Another quick way to get started and find Angular security issues is to use the Snyk CLI:
npm install -g snyk
snyk test
Source: Angular vs React: security bakeoff 2019
Snyk provides actionable remediation advice to upgrade to a fixed version.
If you’re looking for anything close to an Angular security scanner check Snyk out as a way to track your open source dependencies, get notified, and fix them as vulnerabilities get discovered.
Recommended further reading:
If you’re maintaining or doing active development with AngularJS you’ll find the 10 AngularJS Security fundamental best practices useful.
How does Angular vs React compare in terms of their security posture? We released a fully detailed JavaScript Frameworks Security report on it.
Is Angular secure?
The new Angular framework (Angular 2 and above) is regarded as a secure by default framework, demonstrating no known security vulnerabilities. In comparison, its predecessor AngularJS has over 25 publicly known security vulnerabilities, as recent as June 2020. Make sure you follow Angular security best practices, and review Snyk's JavaScript Frameworks Security report for a deep dive on the security of npm modules ecosystem for Angular, React, and other projects.
How to secure an Angular application?
Here are some key fundamental guidelines to ensure a secure Angular application:
1. Make sure that as a developer you are following the “Angular way” and its best practices to protect you from XSS. For example, this means you shouldn't use innerHTML, never use templates generated by concatenating user input, and never use native DOM APIs to interact with HTML elements.
2. Make sure you scan your Angular project for components which introduce security vulnerabilities. Even if you follow Angular's own security practices, other module authors may not, and leave you exposed to severe issues. Do more than scan — fix and monitor for potentially new issues. Snyk is great at that and a free tool you can easily connect to your projects. Read more on Angular security best practices.
Which is more secure angular or react?
The Angular project (Angular 2+) has no publicly known security vulnerabilities. React has 2 security vulnerabilities impacting it, but they are as old as 2017 and you are probably already using a newer version than that. Angular's predecessor — AngularJS, has over 25 security vulnerabilities. If you're still developing or maintaining it be sure to scan your projects with a free developer-first security tool like Snyk. On this topic, you can read the JavaScript Frameworks Security report which investigates the state of security for both the Angular and React ecosystems.
Does angular sanitize input?
Angular by default will output encode all potentially dangerous text that could lead to XSS, given you're following the Angular way of secure coding practices, such as using the double curly braces ({{}}) for safe interpolation. If you however use Angular's innerHTML binding then Angular will try its best to protect you by sanitizing the dangerous content. It should however be your last resort at adding user input.