June 9, 2023 · VIKTORIIA TARAN & AMINA MURTAZINA & NIKITA HORIUK
Angular is a versatile front-end framework that enables direct use of web APIs such as the Window, Document, and Node interfaces. It also has its own wrappers to manipulate the Document Object Model (DOM). Additionally, JavaScript libraries such as jQuery can be used with Angular.
In Part 1, we examined Angular's security model and framework architecture. In Part 2, we cover the following:
- How misuse of Security Context and Security Trust methods leads to XSS, CSS injection, and Open Redirect
- How HTML injection arises in the Angular application
- How user input affects client-side and server-side templates
Bypass Security Trust Methods
Angular introduces a list of methods to bypass its default sanitization process and to indicate that a value can be used safely in a specific context, as in the following five examples:
-
bypassSecurityTrustUrl
is used to indicate the given value is a safe style URL:
CODE: https://gist.github.com/lsg-vtaran/c9efce3bb4477607806035e069ea8519.js
-
bypassSecurityTrustResourceUrl
is used to indicate the given value is a safe resource URL:
CODE: https://gist.github.com/lsg-vtaran/2b946f0be33cfc7e1e06fef901eda954.js
-
bypassSecurityTrustHtml
is used to indicate the given value is safe HTML. Note that inserting script
elements into the DOM tree in this way will not cause them to execute the enclosed JavaScript code, because of how these elements are added to the DOM tree:
CODE: https://gist.github.com/lsg-vtaran/07dce99a784001bad3e44b4adcec3721.js
-
bypassSecurityTrustScript
is used to indicate the given value is safe JavaScript. However, we found its behavior to be unpredictable, because we couldn't execute JS code in templates using this method:
CODE: https://gist.github.com/lsg-vtaran/65d95599fab477d3935e4478a768ac6a.js
-
BypassSecurityTrustStyle
is used to indicate the given value is safe CSS. The following example illustrates CSS injection:
CODE: https://gist.github.com/lsg-vtaran/071dc560206a64efd175868c74c3fe4d.js
Angular provides a sanitize
method to sanitize data before displaying it in views. This method employs the security context provided and cleanses the input accordingly. It is, however, crucial to use the correct security context for the specific data and context. For instance, applying a sanitizer with SecurityContext.URL
on HTML content does not provide protection against dangerous HTML values. In such scenarios, misuse of security context could lead to XSS vulnerabilities.
HTML Injection
This vulnerability occurs when user input is bound to any of these three properties: innerHTML
, outerHTML
, or iframe srcdoc
. While binding to these attributes interprets HTML as it is, the input is sanitized using SecurityContext.HTML
. Thus, HTML injection is possible, but cross-site scripting (XSS) is not.
Example of using innerHTML
:
CODE: https://gist.github.com/lsg-vtaran/28b5b2a118c9fb6ac6020caa2a4a827e.js
The result is <div><h1>test</h1></div>
.
Template Injection
Client-Side Rendering (CSR)
Angular leverages templates to construct pages dynamically. This approach entails enclosing template expressions for Angular to evaluate within double curly brackets ({{}}
). In this way, the framework offers additional functionality. For instance, a template such as {{1+1}}
would display as 2.
Typically, Angular escapes user input that can be confused with template expressions (e.g., characters such as <>`'"
). It means that additional steps are required to circumvent this restriction, such as utilizing functions that generate JavaScript string objects to avoid using blacklisted characters. However, to achieve this, we must consider the Angular context, its properties, and variables. Therefore, a template injection attack may appear as follows:
CODE: https://gist.github.com/lsg-vtaran/3ba18bc44cdf2670d5eb6f4731ae6ae5.js
As shown above: constructor
refers to the scope of the Object constructor
property, enabling us to invoke the String constructor and execute an arbitrary code.
See more payloads here.
Server-Side Rendering (SSR)
Unlike CSR, which occurs in the browser's DOM, Angular Universal is responsible for the SSR of template files. These files are then delivered to the user. Despite this distinction, Angular Universal applies the same sanitization mechanisms used in CSR to enhance SSR security. A template injection vulnerability in SSR can be spotted in the same way as in CSR, because the used template language is the same.
Of course, there also is a possibility of introducing new template injection vulnerabilities when employing third-party template engines such as Pug and Handlebars.
Read more about Angular Universal here.
Conclusion
Now you know how to sleuth out several vulnerabilities in Angular, such as bypassing Security Trust methods, HTML injection, and template injection. Stay tuned for Part 3, where we cover the most common DOM vulnerabilities in Angular. If you should need a recap of Angular's security model, don't hesitate to review the first part of our article!