警告:清理不安全的样式值url

时间:2016-07-26 15:04:45

标签: typescript angular xss

我想在Angular 2应用中的组件模板中设置DIV的背景图像。但是我在控制台中不断收到以下警告,但是我没有达到预期的效果...我不确定动态CSS背景图像是否因为Angular2中的安全限制而被阻止,或者我的HTML模板是否被破坏。

这是我在控制台中看到的警告(我已将我的img网址更改为/img/path/is/correct.png

  

警告:清理不安全的样式值url(SafeValue必须使用[property] = binding:/img/path/is/correct.png(请参阅http://g.co/ng/security#xss))(参见http://g.co/ng/security#xss)。

问题是我使用Angular2中的DomSanitizationService清理注入模板的内容。这是我在模板中的HTML:

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

这是组件......

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>

image使用bypassSecurityTrustUrl传递了一切似乎运作良好...有人能看到我做错了吗?

10 个答案:

答案 0 :(得分:80)

您必须将整个url语句包装在bypassSecurityTrustStyle

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

并且

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

否则,它不会被视为有效的样式属性

答案 1 :(得分:38)

如果背景图像具有线性渐变(*ngFor

查看:

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

上课:

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

答案 2 :(得分:23)

使用此<div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>可以为我解决问题。

答案 3 :(得分:7)

检查Angular2的this方便管道: 用法:

    SafePipe代码中
  1. ,将DomSanitizationService替换为DomSanitizer

  2. 如果您的SafePipe

  3. ,请提供NgModule
  4. <div [style.background-image]="'url(' + your_property + ')' | safe: 'style'"></div>

答案 4 :(得分:3)

有一个未解决的问题,如果实际上有消毒的东西,只打印此警告: https://github.com/angular/angular/pull/10272

当没有消毒时,我没有详细阅读此警告。

答案 5 :(得分:1)

对于已经执行警告建议的人,在升级到Angular 5之前,我必须将SafeStyle类型映射到string,然后才能在模板中使用它们。在Angular 5之后,情况不再如此。我不得不将模型更改为image: SafeStyle而不是image: string。我已经在使用[style.background-image]属性绑定并绕过整个网址的安全性。

希望这有助于某人。

答案 6 :(得分:1)

基于https://angular.io/api/platform-browser/DomSanitizer上的文档,执行此操作的正确方法似乎是使用sanitize。至少在Angular 7中(不知道它是否从以前改变了)。这对我有用:

<ion-item class="light-back" color="light">
  <ion-icon name="search" color="light"></ion-icon>
    <ion-input required type="text" placeholder="Search for a site" color="light">
  </ion-input>
</ion-item>

有关SecurityContext,请参见https://angular.io/api/core/SecurityContext。基本上就是这个枚举:

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 + ')');

答案 7 :(得分:1)

在Angular 7的Image标签中添加动态url时,我遇到了同样的问题。

首先,在组件文件中编写以下代码。

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

现在在html图像标签中,您可以这样编写。

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

您可以根据需要编写内容,而不是 item.imageUrl

我从此站点获得了参考。dynamic urls。 希望此解决方案可以为您提供帮助:)

答案 8 :(得分:0)

由于Angular不是专用的消毒库,因此对可疑内容过分热衷而不承担任何风险。您可以将清理委托给一个专用的库,例如DOMPurify。这是我制作的包装器库,可以轻松地将Angular与DOMPurify结合使用。

https://github.com/TinkoffCreditSystems/ng-dompurify

它具有用于声明性清理HTML的管道:

<div [innerHtml]="value | dompurify"></div>

要记住的一件事是DOMPurify非常适合清理HTML / SVG,而不是CSS。因此,您可以提供Angular的CSS清理程序来处理CSS:

import {NgModule, ɵ_sanitizeStyle} from '@angular/core';
import {SANITIZE_STYLE} from '@tinkoff/ng-dompurify';

@NgModule({
    // ...
    providers: [
        {
            provide: SANITIZE_STYLE,
            useValue: ɵ_sanitizeStyle,
        },
    ],
    // ...
})
export class AppModule {}

它是内部的— ɵ前缀,但这也是Angular团队在其自己的程序包中始终使用它的方式。

答案 9 :(得分:0)

就我而言,我在进入显示组件之前先获得了图像URL,并希望将其用作背景图像,因此要使用该URL,我必须告诉Angular它是安全的并且可以使用。

在.ts文件中

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

在.html文件中

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