Angular lève cette erreur, avec le message unsafe value used in a resource URL context, lorsqu'un template ou un host binding affecte à un attribut qui charge une ressource externe (comme <iframe src> ou <link href>) une valeur qui n'a pas été explicitement marquée comme de confiance.
Les URL de ressource sont traitées différemment des URL classiques. Angular peut assainir une URL simple, mais ne peut pas rendre sûre une URL de ressource arbitraire, car ces attributs amènent le navigateur à récupérer et exécuter du contenu externe. Angular rejette donc les valeurs non fiables au lieu d'essayer de les assainir.
Les attributs concernés par cette vérification sont :
| Élément | Attribut(s) |
|---|---|
<base> |
href |
<embed> |
src |
<frame> |
src |
<iframe> |
src |
<link> |
href |
<object> |
codebase, data |
Déboguer l'erreur
L'erreur est levée dès qu'une chaîne simple est liée à l'un des attributs ci-dessus, même une URL d'apparence statique :
@Component({
selector: 'app-root',
template: `<iframe [src]="url"></iframe>`,
})
export class App {
url = 'https://example.com/embed';
}
Passer la valeur par DomSanitizer.sanitize() avec SecurityContext.URL n'aide pas. sanitize() renvoie une chaîne simple, et une chaîne simple n'est jamais acceptée dans un contexte d'URL de ressource :
@Component({
selector: 'app-root',
template: `<iframe [src]="sanitized"></iframe>`,
})
export class App {
private readonly sanitizer = inject(DomSanitizer);
sanitized = this.sanitizer.sanitize(SecurityContext.URL, 'https://example.com/embed'); // still throws NG0904
}
Appeler sanitize() avec SecurityContext.RESOURCE_URL lève aussi une erreur, mais NG05201, car sanitize() ne peut pas rendre sûre une chaîne arbitraire dans un contexte d'URL de ressource.
Si l'URL provient d'une source contrôlée et de confiance, marquez-la comme sûre avec DomSanitizer.bypassSecurityTrustResourceUrl :
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
import {Component, inject} from '@angular/core';
@Component({
selector: 'app-root',
template: `<iframe [src]="safeUrl"></iframe>`,
})
export class App {
safeUrl: SafeResourceUrl = inject(DomSanitizer).bypassSecurityTrustResourceUrl(
'https://example.com/embed',
);
}
Critique : bypassSecurityTrustResourceUrl est une échappatoire, pas un mécanisme d'assainissement. Ne lui passez jamais d'URL fournies par l'utilisateur : cela permettrait à un attaquant de charger du contenu arbitraire, y compris des scripts malveillants. Ne l'utilisez que lorsque la valeur est entièrement sous votre contrôle.
Pour plus d'informations, consultez le guide de sécurité.