PERINGATAN: membersihkan url nilai gaya yang tidak aman

107

Saya ingin mengatur gambar latar belakang DIV di Template Komponen di aplikasi Angular 2 saya. Namun saya terus mendapatkan peringatan berikut di konsol saya dan saya tidak mendapatkan efek yang diinginkan ... Saya tidak yakin apakah gambar latar belakang CSS dinamis diblokir karena batasan keamanan di Angular2 atau jika template HTML saya rusak.

Ini adalah peringatan yang saya lihat di konsol saya (Saya telah mengubah url img saya menjadi /img/path/is/correct.png:

PERINGATAN: membersihkan url nilai gaya yang tidak aman (SafeValue harus menggunakan [property] = binding: /img/path/is/correct.png (lihat http://g.co/ng/security#xss )) (lihat http: // g.co/ng/security#xss ).

Masalahnya adalah saya membersihkan apa yang disuntikkan ke template saya menggunakan DomSanitizationServicein Angular2. Ini HTML saya yang saya miliki di template saya:

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

Ini komponennya ...

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

            }
        }
    }
}

Harap diperhatikan bahwa ketika saya baru saja terikat ke template menggunakan [src] = "image", misalnya:

<div *ngIf="image">
    <img [src]="image">
</div>

dan imagedisahkan menggunakan bypassSecurityTrustUrlsemuanya tampaknya bekerja dengan baik ... adakah yang bisa melihat apa yang saya lakukan salah?

Mark Sandman
sumber
Apakah Anda mendapatkan solusi untuk pertanyaan Anda. Saya memiliki masalah yang persis sama dan masih berusaha mencari solusi. Terima kasih sebelumnya!
SK.

Jawaban:

112

Anda harus membungkus seluruh urlpernyataan di bypassSecurityTrustStyle:

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

Dan punya

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

Jika tidak, itu tidak dilihat sebagai properti gaya yang valid

Poul Kruijt
sumber
1
PierreDuc, ada kata-kata bijak ketika gambar-latar belakang IS dilewati seperti di atas, tapi kemudian Angular2 diam-diam mengabaikannya? Saya dapat memposting pertanyaan baru tetapi saya pikir itu cukup erat dengan jawaban Anda.
David Pfeffer
@DavidPfeffer Sulit untuk menilai di mana terjadi kesalahan tanpa melihat kode apa pun :) Saya menggunakan kode ini di angular2 terbaru dan masih berfungsi ..
Poul Kruijt
1
Saya menemukan jawabannya. Setelah Anda melewati sanitasi, jika nilainya tidak valid, Angular2 akan mengabaikannya secara diam-diam.
David Pfeffer
Anda harus ngStyle dan itu hanya akan bekerja tanpa mengacaukan sanitasi.
yglodt
Bekerja untuk saya di Angular8. Saya pikir sanitasi yang terbaik ... itu ada karena suatu alasan. @yglobaltv
Sean Halls
67

Gunakan ini <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>memecahkan masalah bagi saya.

iRedia Ebikade
sumber
Aman dan sederhana.
Kenmore
Terima kasih atas kata-kata baik Anda @Kenmore. Saya senang saya bisa membantu. Bersulang.
iRedia Ebikade
@ Sammy-RogersGeek dapatkah saya menulis kode yang sama di tag Gambar?
Arjun
Anda menyelamatkan hari saya!
VAdaihiep
Fasih. Terima kasih.
Tim Mindsect
52

Jika gambar latar belakang dengan gradien linier ( *ngFor)

Melihat:

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

Kelas:

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})`);
}
Swapnil Patwa
sumber
1
Anda menyelamatkan hari saya
Thamaraiselvam
1
Bekerja dengan sempurna :))
Abhijit Srivastava
@AbhijitSrivastava Saya menulis thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url ($ {thumbnail}) )dan [style.backgroundImage]="thumbnailMediumIcon". Versi Angular apa yang Anda gunakan? Saya juga mencoba gambar latar belakang. Apakah ini masih berfungsi? Saya tidak suka pendekatan lain?
MTZ
1
@AbhijitSrivastava Terima kasih! Kesalahan saya, saya melewatkan blob ( thumbnail) dan bukan URL
MTZ
1
Tidak disarankan untuk memanggil ke getBackgrounddalam tampilan, karena Angular harus memanggil bypassSecurityTrustStylesetiap kali tampilan tersebut disegarkan. Untuk menguji yang menambahkan console.log di dalam getBackgrounddan Anda akan melihat fungsi itu dipanggil pada setiap klik atau acara gulir pengguna
Marcin
9

Periksa pipa praktis ini untuk Angular2: Penggunaan:

  1. dalam SafePipekode, gantikan DomSanitizationServicedenganDomSanitizer

  2. sediakan SafePipejika AndaNgModule

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

SimoneMSR
sumber
8

Berdasarkan dokumen di https://angular.io/api/platform-browser/DomSanitizer , cara yang tepat untuk melakukan ini tampaknya menggunakan sanitasi. Setidaknya di Angular 7 (tidak tahu apakah ini berubah dari sebelumnya). Ini berhasil untuk saya:

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

Re SecurityContext, lihat https://angular.io/api/core/SecurityContext . Pada dasarnya hanya enum ini:

enum SecurityContext {
  NONE: 0
  HTML: 1
  STYLE: 2
  SCRIPT: 3
  URL: 4
  RESOURCE_URL: 5
}
Dovev Hefetz
sumber
1
Ini adalah jawaban terbaru. Dapat dipersingkat juga:this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema
@Zahema Saya tidak percaya itu setara dengan jawaban yang diberikan. bypassSecurityTrustStylemengabaikan keamanan sekaligus sanitize(SecurityContext.STYLE, style)memperkuat keamanan. Saya akan merekomendasikan penggunaan sanitizedengan sesuai SecurityContext.
Oscar
@Zahema bypassSecurityTrustStylemengembalikan Objek yang tidak dapat diakses (setidaknya saya tidak dapat melakukannya) di [ngStyle]. sanitize(SecurityContext.STYLE, style)sebagai gantinya mengembalikan string biasa.
Alexander Fink
@Oscar Saya setuju tetapi untuk beberapa alasan itu tidak selalu berfungsi seperti yang diharapkan dalam semua skenario. bypassSecurityTrustStylepada dasarnya kasar memaksanya.
Zahema
6

Saya mendapat masalah yang sama saat menambahkan url dinamis di tag Gambar di Angular 7. Saya banyak mencari dan menemukan solusi ini.

Pertama, tulis kode di bawah ini di file komponen.

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

Sekarang di tag gambar html Anda, Anda dapat menulis seperti ini.

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

Anda dapat menulis sesuai kebutuhan Anda, bukan item.imageUrl

Saya mendapat referensi dari situs ini. url dinamis . Semoga solusi ini akan membantu Anda :)

Arjun
sumber
ini berfungsi untuk gambar, tetapi pertanyaannya adalah tentang gaya URL, menggunakan sebagai gambar latar belakang, yang jawaban ini tidak terkait
Amirreza
3

Ada masalah terbuka untuk hanya mencetak peringatan ini jika sebenarnya ada sesuatu yang dibersihkan: https://github.com/angular/angular/pull/10272

Saya tidak membaca secara detail saat peringatan ini dicetak saat tidak ada yang disanitasi.

Günter Zöchbauer
sumber
3
Bagi mereka yang mungkin datang ke sini: masalah itu telah diselesaikan. Itu hanya mencetak peringatan JIKA membersihkan HTML dan tidak setiap saat.
flamusdiu
Saya ingin tahu apakah itu praktik yang salah? Haruskah saya mencoba untuk tidak mendapatkan peringatan ini?
Amrit
Anda harus sangat berhati-hati saat menerapkan ini ke konten yang disediakan pengguna (seperti teks dari bidang masukan atau konten pengguna yang dimuat dari database atau sumber lain yang tidak Anda kontrol. Dengan cara ini Anda memberi tahu Angular bahwa konten yang secara inheren tidak aman harus diperlakukan sebagai terpercaya. Tidak masalah jika menggunakannya untuk konten statis yang Anda kontrol, seperti konstanta, variabel lingkungan yang diteruskan pada waktu pembuatan, nilai yang dihitung hanya dari nilai yang aman.
Günter Zöchbauer
1

Bagi siapa pun yang sudah melakukan apa yang disarankan peringatan Anda lakukan, sebelum meningkatkan ke Angular 5, saya harus memetakan SafeStyletipe saya stringsebelum menggunakannya di templat. Setelah Angular 5, hal ini tidak berlaku lagi. Aku harus mengubah model saya untuk memiliki image: SafeStylebukan image: string. Saya sudah menggunakan [style.background-image]properti yang mengikat dan melewati keamanan di seluruh url.

Semoga ini bisa membantu seseorang.

Jake Smith
sumber
0

Karena Angular bukan perpustakaan sanitasi khusus, Angular terlalu bersemangat terhadap konten yang mencurigakan untuk tidak mengambil risiko apa pun. Anda dapat mendelegasikan pembersihan ke perpustakaan khusus, misalnya - DOMPurify. Ini adalah pustaka pembungkus yang saya buat untuk menggunakan DOMPurify dengan Angular dengan mudah.

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

Ini memiliki pipa untuk membersihkan HTML secara deklaratif:

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

Satu hal yang perlu diingat adalah DOMPurify sangat bagus untuk membersihkan HTML / SVG, tetapi tidak untuk CSS. Jadi Anda dapat menyediakan pembersih CSS Angular untuk menangani CSS:

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

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

Ini adalah ɵprefiks internal - hense , tapi begitulah cara tim Angular menggunakannya di paket mereka sendiri juga.

waterplea
sumber
-1

Dalam kasus saya, saya mendapatkan URL gambar sebelum masuk ke komponen tampilan dan ingin menggunakannya sebagai gambar latar belakang sehingga untuk menggunakan URL itu saya harus memberi tahu Angular bahwa itu aman dan dapat digunakan.

Dalam file .ts

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

Dalam file .html

<div mat-card-avatar class="nav-header-image" [style.background-image]="userImage"></div>
SANTOSH
sumber
Harap edit jawaban Anda untuk menjelaskannya dan perhatikan mengapa itu adalah jawaban yang lebih baik daripada yang sudah ada.
Dragonthoughts