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

Posted

技术标签:

【中文标题】警告:清理不安全的样式值 url【英文标题】:WARNING: sanitizing unsafe style value url 【发布时间】:2016-11-30 07:35:34 【问题描述】:

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

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

(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 传递的,一切似乎都运行良好......谁能看到我做错了什么?

【问题讨论】:

您的问题得到解决了吗。我有完全相同的问题,仍在尝试找到解决方案。提前致谢! 【参考方案1】:

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

我没有详细阅读此警告时打印此警告时没有进行任何清理。

【讨论】:

对于那些可能来到这里的人:该问题已得到解决。如果它清理了 HTML,它只会打印警告,而不是一直打印。 我想知道这样做是错误的做法吗?我应该尽量不收到这个警告吗? 当您将其应用于用户提供的内容(例如来自输入字段的文本或从数据库或其他您不提供的来源加载的用户内容)时,您应该非常谨慎控制。这样你告诉 Angular 本质上不安全的内容应该被视为可信赖的。尽管将它用于你控制的静态内容是完全可以的,比如常量,在构建时传递的环境变量,仅从这些安全值计算的值。 【参考方案2】:

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

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

还有

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

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

【讨论】:

PierreDuc,当背景图像被如上所述绕过时,有什么智慧的话,但是 Angular2 默默地忽略它?我可以发布一个新问题,但我认为它与您的回答密切相关。 @DavidPfeffer 在没有看到任何代码的情况下很难判断哪里出了问题 :) 我在最新的 angular2 中使用了这段代码,它仍然可以工作.. 我想通了。绕过清理后,如果该值无效,Angular2 会默默地忽略它。 您应该使用 ngStyle,它可以正常工作而不会弄乱消毒。 在 Angular8 中为我工作。我认为消毒是最好的……它的存在是有原因的。 @yglodt。【参考方案3】:

如果背景图像具有线性渐变 (*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)`);

【讨论】:

你拯救了我的一天 完美运行 :)) 迄今为止的最新版本。是的,它正在工作。 @AbhijitSrivastava 谢谢!我的错误,我传递了一个 blob (thumbnail) 而不是 URL 不建议在视图内部调用getBackground,因为Angular每次刷新视图时都必须调用bypassSecurityTrustStyle。要测试在getBackground 中添加console.log,您将看到每次单击或用户滚动事件都会调用该函数【参考方案4】:

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

希望这对某人有所帮助。

【讨论】:

【参考方案5】:

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

    SafePipe 代码中,将DomSanitizationService 替换为DomSanitizer

    如果您的NgModule,请提供SafePipe

    &lt;div [style.background-image]="'url(' + your_property + ')' | safe: 'style'"&gt;&lt;/div&gt;

【讨论】:

【参考方案6】:

使用这个&lt;div [ngStyle]="'background-image':'url('+imageUrl+')'"&gt;&lt;/div&gt; 这解决了我的问题。

【讨论】:

安全简单。 感谢您的客气话@Kenmore。我很高兴能帮上忙。干杯。 @Sammy-RogersGeek 我可以在 Image 标签中写同样的代码吗? 你拯救了我的一天! 雄辩。谢谢。【参考方案7】:

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

【讨论】:

这是最新的答案。也可以缩短:this.sanitizer.bypassSecurityTrustStyle(`url('$this.image ')`); @Zahema 我不认为这等同于提供的答案。 bypassSecurityTrustStyle 忽略安全性,而 sanitize(SecurityContext.STYLE, style) 加强安全性。我建议使用sanitize 和适当的SecurityContext @Zahema bypassSecurityTrustStyle[ngStyle] 中返回一个无法访问的对象(至少我做不到)。 sanitize(SecurityContext.STYLE, style) 而是返回一个纯字符串。 @Oscar 我同意,但由于某种原因,它并不总是在所有情况下都按预期工作。 bypassSecurityTrustStyle 基本上是暴力破解。【参考方案8】:

我在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。 希望这个解决方案能帮到你:)

【讨论】:

它适用于图像,但问题是关于样式中的 URL,用作背景图像,这个答案是无关的【参考方案9】:

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

【讨论】:

请编辑您的答案以解释它,并注意为什么它比任何现有的答案都更好。

以上是关于警告:清理不安全的样式值 url的主要内容,如果未能解决你的问题,请参考以下文章

laravel 在使用 url 传递值时不加载样式

“导航项中不支持普通样式”警告我的自定义条形按钮项

在HTTP页面输入数据,Chrome 70将显示红色不安全警告

Gatsby - 警告尝试导入错误:“css”不包含默认导出(导入为“样式”)

使用nokogiri剥离样式属性

material-ui 客户端警告:道具“样式”不匹配