87 lines
3.2 KiB
Plaintext
87 lines
3.2 KiB
Plaintext
Angular prevents XSS vulnerabilities by treating all values as untrusted by default. Untrusted values are systematically sanitized by the framework before they are inserted into the DOM.
|
|
|
|
Still, developers have the ability to manually mark a value as trusted if they are sure that the value is already sanitized. Accidentally trusting malicious data will introduce an XSS vulnerability in the application and enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.
|
|
|
|
|
|
== Ask Yourself Whether
|
|
|
|
* The value for which sanitization has been disabled is user-controlled.
|
|
* It's difficult to understand how this value is constructed.
|
|
|
|
There is a risk if you answered yes to any of those questions.
|
|
|
|
|
|
== Recommended Secure Coding Practices
|
|
|
|
* Avoid including dynamic executable code and thus disabling Angular's built-in sanitization unless it's absolutely necessary. Try instead to rely as much as possible on static templates and Angular built-in sanitization to define web page content.
|
|
* Make sure to understand how the value to consider as trusted is constructed and never concatenate it with user-controlled data.
|
|
* Make sure to choose the correct https://angular.io/api/platform-browser/DomSanitizer[DomSanitizer] "bypass" method based on the context. For instance, only use ``++bypassSecurityTrustUrl++`` to trust urls in an ``++href++`` attribute context.
|
|
|
|
|
|
== Sensitive Code Example
|
|
|
|
----
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
|
|
import { ActivatedRoute } from '@angular/router';
|
|
|
|
@Component({
|
|
template: '<div id="hello" [innerHTML]="hello"></div>'
|
|
})
|
|
export class HelloComponent implements OnInit {
|
|
hello: SafeHtml;
|
|
|
|
constructor(private sanitizer: DomSanitizer, private route: ActivatedRoute) { }
|
|
|
|
ngOnInit(): void {
|
|
let name = this.route.snapshot.queryParams.name;
|
|
let html = "<h1>Hello " + name + "</h1>";
|
|
this.hello = this.sanitizer.bypassSecurityTrustHtml(html); // Sensitive
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
== Compliant Solution
|
|
|
|
[source,javascript]
|
|
----
|
|
import { Component, OnInit } from '@angular/core';
|
|
import { DomSanitizer } from "@angular/platform-browser";
|
|
import { ActivatedRoute } from '@angular/router';
|
|
|
|
@Component({
|
|
template: '<div id="hello"><h1>Hello {{name}}</h1></div>',
|
|
})
|
|
export class HelloComponent implements OnInit {
|
|
name: string;
|
|
|
|
constructor(private sanitizer: DomSanitizer, private route: ActivatedRoute) { }
|
|
|
|
ngOnInit(): void {
|
|
this.name = this.route.snapshot.queryParams.name;
|
|
}
|
|
}
|
|
----
|
|
|
|
== See
|
|
|
|
* OWASP - https://owasp.org/Top10/A03_2021-Injection/[Top 10 2021 Category A3 - Injection]
|
|
* OWASP - https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS)[Top 10 2017 Category A7 - Cross-Site Scripting (XSS)]
|
|
* CWE - https://cwe.mitre.org/data/definitions/79[CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')]
|
|
* https://angular.io/guide/security[Angular - Best Practices - Security]
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Make sure disabling Angular built-in sanitization is safe here.
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|