WARNING: sanitizing unsafe style value url

I want to set the background image of a DIV in a Component Template in my Angular 2 app. However I keep getting the following warning in my console and I don't get the desired effect... I am unsure if the dynamic CSS background image is being blocked due to security restrictions in Angular2 or if my HTML template is broken.

This is the warning I see in my console (I have changed my img url to /img/path/is/correct.png:

WARNING: sanitizing unsafe style value url(SafeValue must use [property]=binding: /img/path/is/correct.png (see http://g.co/ng/security#xss)) (see http://g.co/ng/security#xss).

The thing is I do sanitize what is injected into my template using the DomSanitizationService in Angular2. Here is my HTML that I have in my template:

<div>
<div>
<div class="header"
*ngIf="image"
[style.background-image]="'url(' + image + ')'">
</div>


<div class="zone">
<div>
<div>
<h1 [innerHTML]="header"></h1>
</div>
<div class="zone__content">
<p
*ngFor="let contentSegment of content"
[innerHTML]="contentSegment"></p>
</div>
</div>
</div>
</div>
</div>

Here is the component...

Import {
DomSanitizationService,
SafeHtml,
SafeUrl,
SafeStyle
} from '@angular/platform-browser';


@Component({
selector: 'example',
templateUrl: 'src/content/example.component.html'
})
export class CardComponent implements OnChanges {


public header:SafeHtml;
public content:SafeHtml[];
public image:SafeStyle;
public isActive:boolean;
public isExtended:boolean;


constructor(private sanitization:DomSanitizationService) {
}


ngOnChanges():void {
map(this.element, this);


function map(element:Card, instance:CardComponent):void {
if (element) {
instance.header = instance.sanitization.bypassSecurityTrustHtml(element.header);


instance.content = _.map(instance.element.content, (input:string):SafeHtml => {
return instance.sanitization.bypassSecurityTrustHtml(input);
});


if (element.image) {
/* Here is the problem... I have also used bypassSecurityTrustUrl */
instance.image = instance.sanitization.bypassSecurityTrustStyle(element.image);
} else {
instance.image = null;
}


}
}
}
}

请注意,当我使用[SRC]=“ image ”绑定到模板时,例如:

<div *ngIf="image">
<img [src]="image">
</div>

and image was passed using bypassSecurityTrustUrl everything seemed to work well... can anyone see what I am doing wrong?

161655 次浏览

There is an open issue to only print this warning if there was actually something sanitized: https://github.com/angular/angular/pull/10272

I didn't read in detail when this warning is printed when nothing was sanitized.

You have to wrap the entire url statement in the bypassSecurityTrustStyle:

<div class="header" *ngIf="image" [style.background-image]="image"></div>

And have

this.image = this.sanitization.bypassSecurityTrustStyle(`url(${element.image})`);

Otherwise it is not seen as a valid style property

If background image with linear-gradient (*ngFor)

View:

<div [style.background-image]="getBackground(trendingEntity.img)" class="trending-content">
</div>

Class:

import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';


constructor(private _sanitizer: DomSanitizer) {}


getBackground(image) {
return this._sanitizer.bypassSecurityTrustStyle(`linear-gradient(rgba(29, 29, 29, 0), rgba(16, 16, 23, 0.5)), url(${image})`);
}

For anyone who is already doing what the warning suggests you do, before the upgrade to Angular 5, I had to map my SafeStyle types to string before using them in the templates. After Angular 5, this is no longer the case. I had to change my models to have an image: SafeStyle instead of image: string. I was already using the [style.background-image] property binding and bypassing security on the whole url.

Hope this helps someone.

Check this handy pipe for Angular2: Usage:

  1. in the SafePipe code, substitute DomSanitizationService with DomSanitizer

  2. provide the SafePipe if your NgModule

  3. <div [style.background-image]="'url(' + your_property + ')' | safe: 'style'"></div>

Use this <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div> this solved the problem for me.

Based on the docs at https://angular.io/api/platform-browser/DomSanitizer, the right way to do this seems to be to use sanitize. At least in Angular 7 (don't know if this changed from before). This worked for me:

import { Component, OnInit, Input, SecurityContext } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';


constructor(
private sanitizer: DomSanitizer
) { }


this.sanitizer.sanitize(SecurityContext.STYLE, 'url(' + this.image + ')');

Re SecurityContext, see https://angular.io/api/core/SecurityContext. Basically it's just this enum:

enum SecurityContext {
NONE: 0
HTML: 1
STYLE: 2
SCRIPT: 3
URL: 4
RESOURCE_URL: 5
}

I got the same issue while adding dynamic url in Image tag in Angular 7. I searched a lot and found this solution.

First, write below code in the component file.

constructor(private sanitizer: DomSanitizer) {}
public getSantizeUrl(url : string) {
return this.sanitizer.bypassSecurityTrustUrl(url);
}

Now in your html image tag, you can write like this.

<img class="image-holder" [src]=getSantizeUrl(item.imageUrl) />

You can write as per your requirement instead of item.imageUrl

I got a reference from this site.dynamic urls. Hope this solution will help you :)

In my case, I got the image URL before getting to the display component and want to use it as the background image so to use that URL I have to tell Angular that it's safe and can be used.

In .ts file

userImage: SafeStyle;
ngOnInit(){
this.userImage = this.sanitizer.bypassSecurityTrustStyle('url(' + sessionStorage.getItem("IMAGE") + ')');
}

In .html file

<div mat-card-avatar class="nav-header-image" [style.background-image]="userImage"></div>

In my case, I needed the functionality of sanitizing in more than one component. Implementing a pipe was the most suitable and elegant way for solving this problem.

Implementation:

@Pipe({
name: 'sanitizer'
})
export class SanitizerPipe implements PipeTransform {


constructor(private sanitizer: DomSanitizer) {}


transform(value: any, args?: any): any {
return this.sanitizer.bypassSecurityTrustUrl(value);
}
}

Using the pipe:

<img [src]="pictureSrc | sanitizer" alt="selected picture">