Angular Security: The Definitive Guide (Part 1)
We are happy to share our methodology and security guide on how to do security reviews of Angular applications. In this article we will talk about the architecture and security model of Angular to build a solid foundation for future parts.
May 29, 2023 · VIKTORIIA TARAN & AMINA MURTAZINA & NIKITA HORIUK
Disclaimer: This work only covers Angular and related methods, classes, JavaScript libraries, and Web APIs. AngularJS is not included as it is no longer maintained after January 2022.
This article provides an overview of Angular's security model and framework architecture. It begins with an explanation of Angular and its security mechanisms, followed by a discussion of the framework's architecture and project structure. The article also covers concepts important to understand Angular security such as sourcemap configuration, data binding, and the six types of SecurityContext
.
What is Angular
Angular is a powerful front-end framework that is widely used for building dynamic web applications. It is open-source and maintained by Google. One of the key features of Angular is its use of TypeScript, a typed superset of JavaScript that makes code easier to read, maintain, and debug.
Angular's security mechanisms are designed to prevent common client-side vulnerabilities, including cross-site scripting (XSS) and open redirects. However, Angular can also be used on the server-side to generate static pages. Thus, the security of Angular should be considered from both sides.
Framework architecture
In order to better understand the Angular basics, let’s go through its essential concepts.
Common Angular project usually looks like:
CODE: https://gist.github.com/lsg-vtaran/2c1484491b997a9778af450a4833f805.js
According to the documentation, every Angular application has at least one component, the root component (AppComponent
) that connects a component hierarchy with the DOM. Each component defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment. The @Component()
decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata. The AppComponent
is defined in the app.component.ts
file.
Angular NgModules declare a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. Every Angular application has a root module, conventionally named AppModule
, which provides the bootstrap mechanism that launches the application. An application typically contains many functional modules. The AppModule
is defined in the app.module.ts
file.
The Angular Router
NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your application. The RouterModule
is defined in the app-routing.module.ts
file.
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a service class. A service class definition is immediately preceded by the @Injectable()
decorator. The decorator provides the metadata that allows other providers to be injected as dependencies into your class. Dependency injection (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.
References
Sourcemap configuration
Angular framework translates TypeScript files into JavaScript code by following tsconfig.json
options and then builds a project with angular.json
configuration. Looking at angular.json
file, we observed an option to enable or disable a sourcemap. According to the Angular documentation, the default configuration has a sourcemap file enabled for scripts and is not hidden by default:
CODE: https://gist.github.com/lsg-vtaran/765256d75134bca350f7e45cc8ccb8b4.js
Generally, sourcemap files are utilized for debugging purposes as they map generated files to their original files. Therefore, it is not recommended to use them in a production environment. If sourcemaps are enabled, it improves the readability and aids in file analysis by replicating the original state of the Angular project. However, if they are disabled, a reviewer can still analyze a compiled JavaScript file manually by searching for anti-security patterns.
Furthemore, a compiled JavaScript file with an Angular project can be found in the browser developer tools → Sources (or Debugger and Sources) → [id].main.js. Depending on the enabled options, this file may contain the following row in the end //# sourceMappingURL=[id].main.js.map
or it may not, if the hidden option is set to true. Nonetheless, if the sourcemap is disabled for scripts, testing becomes more complex, and we cannot obtain the file. In addition, sourcemap can be enabled during project build like ng build --source-map
.
More details at https://angular.io/guide/workspace-config#source-map-configuration.
Data binding
Binding refers to the process of communication between a component and its corresponding view. It is utilized for transferring data to and from the Angular framework. Data can be passed through various means, such as through events, interpolation, properties, or through the two-way binding mechanism. Moreover, data can also be shared between related components (parent-child relation) and between two unrelated components using the Service feature.
We can classify binding by data flow:
- Data source to view target (includes interpolation, properties, attributes, classes and styles); can be applied by using
[]
or{{}}
in template; - View target to data source (includes events); can be applied by using
()
in template; - Two-Way; can be applied by using
[()]
in template.
Binding can be called on properties, events, and attributes, as well as on any public member of a source directive:
TYPE | TARGET | EXAMPLES |
---|---|---|
Property | Element property, component property, directive property | <img [alt]="hero.name" [src]="heroImageUrl"> |
Event | Element event, component event, directive event | <button type="button" (click)="onSave()">Save |
Two-way | Event and property | <input [(ngModel)]="name"> |
Attribute | Attribute (the exception) | <button type="button" [attr.aria-label]="help">help |
Class | class property | <div [class.special]="isSpecial">Special |
Style | style property | <button type="button" [style.color]="isSpecial ? 'red' : 'green'"> |
References
- https://angular.io/guide/binding-syntax
- Angular Context: Easy Data-Binding for Nested Component Trees and the Router Outlet
Angular security model
Angular's design includes encoding or sanitization of all data by default, making it increasingly difficult to discover and exploit XSS vulnerabilities in Angular projects. There are two distinct scenarios for data handling:
-
Interpolation or
{{user_input}}
- performs context-sensitive encoding and interprets user input as text;CODE: https://gist.github.com/lsg-vtaran/fc583e009586f3e86e39e33ca9903d8d.js
Result:
<script>alert(1)</script><h1>test</h1>
-
Binding to properties, attributes, classes and styles or
[attribute]="user_input"
- performs sanitization based on the provided security context.CODE: https://gist.github.com/lsg-vtaran/6962b824c60ac0d72461a3410cfed868.js
Result:
<div><h1>test</h1></div>
There are 6 types of SecurityContext
:
None
;HTML
is used, when interpreting value as HTML;STYLE
is used, when binding CSS into thestyle
property;URL
is used for URL properties, such as<a href>
;SCRIPT
is used for JavaScript code;RESOURCE_URL
as a URL that is loaded and executed as code, for example, in<script src>
.
References
- https://angular.io/guide/security#sanitization-and-security-contexts
- GitHub - angular/dom_security_schema.ts
Conclusion
In this article we covered Angular's security model and framework architecture, including a discussion of the typical project structure and security mechanisms.
Don't miss next week's article, where we'll delve into potential vulnerabilities in Angular projects, including bypassing Security Trust methods and HTML/template injections. Stay informed and stay safe!
News & Updates...
We are happy to share our methodology and security guide on how to do security reviews for Ruby on Rails applications through source code. In the article you will get an idea about the architecture and design of Ruby on Rails, present security checklist to increase the coverage for penetration testing assessments, and review how to find and exploit most of the OWASP 10 vulnerabilities.
XSS can be particularly devastating to Electron apps, and can result in RCE and phishing that might not be viable in a browser. Electron has features to mitigate these problems, so applications should turn them on. Even XSS that would be low-impact in the browser can result in highly effective phishing if the application’s URL allowlist is improperly designed. Attacks exploit the Electron model and the application-like presentation of Electron to gain the user’s confidence.
All Rights Reserved 2023