WARNING: sanitizing unsafe style value url

149,482

Solution 1

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

Solution 2

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

Solution 3

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})`);
}

Solution 4

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

Solution 5

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>

Share:
149,482
Mark Sandman
Author by

Mark Sandman

There's no much to tell...

Updated on December 25, 2020

Comments

  • Mark Sandman
    Mark Sandman over 3 years

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

    Please note that when I just bound to the template using [src]="image", for example:

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

  • David Pfeffer
    David Pfeffer over 7 years
    PierreDuc, any words of wisdom for when background-image IS bypassed as above, but then Angular2 silently ignores it? I can post a new question but I think its fairly germane to your answer.
  • Poul Kruijt
    Poul Kruijt over 7 years
    @DavidPfeffer It's difficult to judge where things go wrong without seeing any code :) I use this code in the latest angular2 and it's still working..
  • David Pfeffer
    David Pfeffer over 7 years
    I figured it out. After you bypass sanitization, if the value is invalid, Angular2 silently ignores it.
  • flamusdiu
    flamusdiu almost 7 years
    For those that might come here: that issue has been resolved. It only prints the warning IF it sanitized HTML and not all the time.
  • Thamaraiselvam
    Thamaraiselvam over 5 years
    you saved my day
  • Kenmore
    Kenmore about 5 years
    Safe and simple.
  • iRedia Ebikade
    iRedia Ebikade about 5 years
    Thanks for your kind words @Kenmore. I'm glad I could be of help. Cheers.
  • Abhijit Srivastava
    Abhijit Srivastava about 5 years
    Works perfectly :))
  • Mateut Alin
    Mateut Alin about 5 years
    @AbhijitSrivastava I wrote thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url(${thumbnail})) and [style.backgroundImage]="thumbnailMediumIcon". What Angular version did you use? I also tried background-image. Is this still working? I don't like the other approach?
  • Abhijit Srivastava
    Abhijit Srivastava about 5 years
    The very latest version till today. And yes it is working.
  • Mateut Alin
    Mateut Alin about 5 years
    @AbhijitSrivastava Thanks! My mistake, I passed a blob (thumbnail) instead of a URL
  • Arjun
    Arjun almost 5 years
    @Sammy-RogersGeek can I write same code in Image tag?
  • VAdaihiep
    VAdaihiep almost 5 years
    You save my day!
  • Marcin
    Marcin over 4 years
    It's not recommended to call getBackground inside the view, because Angular has to call bypassSecurityTrustStyle each time that view is refreshed. To test that add console.log inside getBackground and you will see that function is called on each click or user scroll event
  • yglodt
    yglodt over 4 years
    You should ngStyle and it will just work without messing with sanitizing.
  • Zahema
    Zahema over 4 years
    This is the most up to date answer. It can be shortned too: this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
  • Amrit
    Amrit over 4 years
    I wanted to know is it wrong practice to do so ? Should i try not to get this warning?
  • Günter Zöchbauer
    Günter Zöchbauer over 4 years
    You should be very cautious when you apply this to user-provided content (like text from an input field or user content loaded from a database or other sources you don't control. This way you tell Angular that inherently unsafe content should be treated as trustworty. It's totally fine though to use it for static content that you control, like constants, environment variables passed at build time, values calculated only from such safe values.
  • Amirreza
    Amirreza over 4 years
    it works for images, but question was about URL in style, using as background image, which this answer is unrelated
  • Dragonthoughts
    Dragonthoughts over 4 years
    Please edit your answer to explain it and note why it is a better answer than any of the existing ones.
  • Sean Halls
    Sean Halls over 4 years
    Worked for me in Angular8. I think that sanitizing is best... it exists for a reason. @yglodt.
  • Oscar
    Oscar about 4 years
    @Zahema I don't believe that is equivalent to the answer provided. bypassSecurityTrustStyle ignores security while sanitize(SecurityContext.STYLE, style) reinforces security. I would recommend using sanitize with the appropriate SecurityContext.
  • afcode
    afcode about 4 years
    @Zahema bypassSecurityTrustStyle returns an Object that can not be accessed (at least I could not do it) in [ngStyle]. sanitize(SecurityContext.STYLE, style) instead returns a plain string.
  • Zahema
    Zahema about 4 years
    @Oscar I agree but for some reason it doesn't always work as expected in all scenarios. bypassSecurityTrustStyle is basicly brute forcing it.
  • Mindsect Team
    Mindsect Team almost 4 years
    Eloquent. Thank you.
  • Eric Aig
    Eric Aig about 3 years
    This worked for me! Thank u. I had to do a little modification for the code to work tho. I added this linkCapacitor.convertFileSrc(image) to the code. To trust the image path. If you are using Cordova, then use this linkwindow.Ionic.WebView.convertFileSrc(image) getBackground(image) { return this._sanitizer.bypassSecurityTrustStyle(linear-gradient(rgb‌​a(29, 29, 29, 0), rgba(16, 16, 23, 0.5)), url(${Capacitor.convertFileSrc(image)})); }