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 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
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