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

问题描述 投票:0回答:10

我想在 Angular 2 应用程序的组件模板中设置 DIV 的背景图像。然而,我不断在控制台中收到以下警告,但没有得到所需的效果...我不确定动态 CSS 背景图像是否由于 Angular2 中的安全限制而被阻止,或者我的 HTML 模板是否已损坏。

这是我在控制台中看到的警告(我已将我的 img url 更改为

/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
通过了,一切似乎都运行良好......任何人都可以看到我做错了什么吗?

typescript angular xss
10个回答
123
投票

您必须将整个

url
语句包装在
bypassSecurityTrustStyle
中:

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

并且有

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

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


78
投票

使用这个

<div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>
这解决了我的问题。


59
投票

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

*ngFor

查看:

<div [style.background-image]="getBackground(product.img)">
</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})`);
}

23
投票

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

我从这个网站获得了参考。动态网址。 希望这个解决方案能帮助你:)


11
投票

检查 Angular2 的 this 便捷管道: 用途:

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

  2. 如果您的

    SafePipe
    ,请提供 

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


8
投票

根据https://angular.io/api/platform-browser/DomSanitizer的文档,正确的方法似乎是使用 sanitize。至少在 Angular 7 中是这样(不知道这与以前相比是否有所改变)。这对我有用:

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

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

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

4
投票

就我而言,我需要多个组件具有消毒功能。 实现管道是解决这个问题最合适、最优雅的方式。

实施:

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

  constructor(private sanitizer: DomSanitizer) {}

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

使用管道:

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

3
投票

有一个未解决的问题,即仅在确实有某些内容已清理的情况下才打印此警告: https://github.com/angular/angular/pull/10272

当没有清理任何内容时打印此警告时,我没有详细阅读。


3
投票

就我而言,我在到达显示组件之前获得了图像 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>

1
投票

对于任何已经按照警告建议您执行操作的人来说,在升级到 Angular 5 之前,我必须将我的

SafeStyle
类型映射到
string
,然后才能在模板中使用它们。在 Angular 5 之后,情况不再如此。我必须更改模型以使用
image: SafeStyle
而不是
image: string
。我已经在使用
[style.background-image]
属性绑定并绕过整个 url 的安全性。

希望这对某人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.