警告:安全でないスタイル値のURLをサニタイズしています


107

Angular 2アプリのコンポーネントテンプレートでDIVの背景画像を設定したいと思います。しかし、コンソールに次の警告が表示され続け、目的の効果が得られません... Angular2のセキュリティ制限のために動的CSS背景画像がブロックされているのか、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)。

問題はDomSanitizationService、Angular2 を使用してテンプレートに注入されたものをサニタイズすることです。テンプレートにある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すべてのものをうまく動作するように見えた...缶誰も私が間違ってやっているものを参照してください?


あなたはあなたの質問に対する解決策を得ましたか?私はまったく同じ問題を抱えていますが、解決策を見つけようとしています。前もって感謝します!
SK。

回答:


112

urlステートメント全体をで囲む必要がありますbypassSecurityTrustStyle

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

そして持っている

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

それ以外の場合は、有効なスタイルプロパティとは見なされません。


1
PierreDuc、背景画像が上記のようにバイパスされるときの知恵の言葉はありますが、Angular2は黙ってそれを無視しますか?新しい質問を投稿できますが、あなたの回答にはかなり密接に関連していると思います。
David Pfeffer 2016

@DavidPfefferそれの困難な物事はすべてのコードを見ずに間違って行くところ:)私は、最新のangular2にこのコードを使用し、それはまだ働いて判断する。..
POUL Kruijt

1
私はそれを考え出した。サニタイズをバイパスした後、値が無効な場合、Angular2は警告なしで無視します。
David Pfeffer 2016

ngStyleを使用する必要があります。サニタイズをいじることなく機能します。
yglodt

Angular8で私のために働いた。除菌は最高だと思います…それは理由があって存在しています。@yglodt。
ショーンホールズ

67

これを使用して、<div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>これで問題が解決しました。


安全でシンプル。
ケンモア2019

@Kenmoreの親切な言葉をありがとう。お役に立ててよかったです。乾杯。
iRedia Ebikade

@ Sammy-RogersGeekはイメージタグに同じコードを記述できますか?
アルジュン

あなたは私の日を救います!
VAdaihiep

雄弁。ありがとうございました。
Mindsectチーム

52

線形グラデーション(*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})`);
}

1
あなたは私の日を救った
Thamaraiselvam

1
完璧に動作します:))
Abhijit Srivastava

@AbhijitSrivastava thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url($ {thumbnail}))[style.backgroundImage]="thumbnailMediumIcon"。どのAngularバージョンを使用しましたか?背景画像も試しました。これはまだ機能していますか?他のアプローチが気に入らないのですか?
MTZ 2019年

1
@AbhijitSrivastavaありがとう!私の間違い、thumbnailURLの代わりにblob()を渡しました
MTZ

1
getBackgroundAngularはbypassSecurityTrustStyleビューが更新されるたびに呼び出す必要があるため、ビュー内で呼び出すことはお勧めしません。console.log内部を追加し、テストするgetBackgroundと、あなたはその関数が各クリック、またはユーザのスクロールイベントに呼ばれて表示されます
マルチン

9

Angular2のこの便利なパイプを確認してください:使用法:

  1. SafePipeコード、代わりDomSanitizationServiceDomSanitizer

  2. SafePipeあなたの場合NgModule

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


8

https://angular.io/api/platform-b​​rowser/DomSanitizerのドキュメントに基づいて、これを行う正しい方法は、サニタイズを使用することです。少なくとも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
}

1
これが最新の答えです。それはあまりにもshortnedすることができますthis.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema

@Zahemaそれが提供された答えに相当するとは思わない。bypassSecurityTrustStyleセキュリティをsanitize(SecurityContext.STYLE, style)強化しながらセキュリティを無視します。sanitize適切なで使用することをお勧めしますSecurityContext
オスカー

@Zahema bypassSecurityTrustStyleは、にアクセスできない(少なくとも私はできなかった)オブジェクトを返します[ngStyle]sanitize(SecurityContext.STYLE, style)代わりに、プレーンな文字列を返します。
アレクサンダーフィンク

@オスカー私も同意しますが、何らかの理由ですべてのシナリオで期待どおりに機能するとは限りません。bypassSecurityTrustStyle基本的に野蛮な強制です。
Zahema

6

Angular 7の画像タグに動的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の代わりにあなたの要件ごとに書くことができます

このサイトから参考になりました。動的URL。このソリューションがあなたを助けることを願っています:)


画像に対しては機能しますが、質問は背景画像として使用するスタイルのURLに関するものでした。この回答は無関係です
Amirreza

3

実際にサニタイズされたものがあった場合にのみこの警告を出力するという未解決の問題がありますhttps : //github.com/angular/angular/pull/10272

何もサニタイズされていないときにこの警告が出力されるとき、私は詳細を読みませんでした。


3
ここに来るかもしれない人のために:その問題は解決されました。常にではなく、HTMLをサニタイズした場合にのみ警告を出力します。
flamusdiu 2017

私が知りたいのは、そうするのは間違った習慣ですか?この警告を受け取らないようにすべきですか?
アムリット

これをユーザー提供のコンテンツ(入力フィールドからのテキストや、データベースや制御できない他のソースから読み込まれたユーザーコンテンツなど)に適用する場合は、非常に注意する必要があります。これにより、本質的に安全でないコンテンツをtrustworty定数、ビルド時に渡される環境変数、のみ、そのような安全な値から算出した値と同じように、あなたがコントロールすることを静的コンテンツのためにそれを使用するためにかかわらず、それは完全に罰金です。。
ギュンターZöchbauer

1

Angular 5にアップグレードする前に、警告が示唆することを既に実行している人は、テンプレートで使用する前にSafeStyleタイプをマッピングstringする必要がありました。Angular 5以降、これは当てはまりません。のimage: SafeStyle代わりにを使用するようにモデルを変更する必要がありましたimage: string。私はすでに[style.background-image]プロパティバインディングを使用しており、URL全体でセキュリティをバイパスしていました。

これが誰かを助けることを願っています。


0

Angularは専用のサニタイジングライブラリではないため、不審なコンテンツに対してリスクを負わずに過熱しています。たとえば、DOMPurifyなどの専用ライブラリにサニタイズを委任できます。以下は、AngularでDOMPurifyを簡単に使用するために作成したラッパーライブラリです。

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

HTMLを宣言的にサニタイズするパイプがあります。

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

DOMPurifyはHTML / SVGのサニタイズには最適ですが、CSSには適していません。したがって、CSSを処理するためにAngularの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チームが独自のパッケージ全体で使用する方法です。


-1

私の場合、表示コンポーネントに到達する前に画像の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>

回答を編集して説明し、既存の回答よりも優れた回答である理由を書き留めてください。
Dragonthoughts、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.