UYARI: güvenli olmayan stil değeri url'sini temizleme


107

Angular 2 uygulamamdaki bir Bileşen Şablonunda bir DIV'nin arka plan resmini ayarlamak istiyorum. Ancak konsolumda aşağıdaki uyarıyı almaya devam ediyorum ve istenen etkiyi alamıyorum ... Dinamik CSS arka plan görüntüsünün Angular2'deki güvenlik kısıtlamaları nedeniyle engellenip engellenmediğinden veya HTML şablonumun bozuk olup olmadığından emin değilim.

Konsolumda gördüğüm uyarı bu (img url’mi şu şekilde değiştirdim /img/path/is/correct.png:

UYARI: güvensiz stil değeri url sterilize (SafeValue [özelliğini] kullanmalıdır = bağlayıcı: /img/path/is/correct.png (bkz http://g.co/ng/security#xss )) (bkz : http: // g.co/ng/security#xss ).

DomSanitizationServiceMesele şu ki , şablonuma enjekte edilenleri Angular2'de kullanarak sterilize ediyorum. Şablonumda bulunan HTML’im şu şekildedir:

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

İşte bileşen ...

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

            }
        }
    }
}

Lütfen [src] = "image" kullanarak şablona bağlandığımda, örneğin:

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

ve her şey iyi çalışıyor gibiydi imagekullanarak geçti bypassSecurityTrustUrl... kimse neyi yanlış yaptığımı görebilir mi?


Sorunuza çözüm buldunuz mu? Tam olarak aynı sorunu yaşıyorum ve hala bir çözüm bulmaya çalışıyorum. Şimdiden teşekkürler!
SK.

Yanıtlar:


112

Tüm urlifadeyi şu şekilde sarmalısınız bypassSecurityTrustStyle:

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

Ve sahip

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

Aksi takdirde geçerli bir stil özelliği olarak görülmez


1
PierreDuc, arka plan görüntüsünün yukarıdaki gibi atlandığı, ancak Angular2 sessizce görmezden geldiği zaman için akıllıca bir söz var mı? Yeni bir soru gönderebilirim ama bence cevabınızla oldukça alakalı.
David Pfeffer

@DavidPfeffer Herhangi bir kod görmeden işlerin nerede yanlış gittiğini yargılamak zor :) Bu kodu en son angular2'de kullanıyorum ve hala çalışıyor ..
Poul Kruijt

1
Bunu anladım. Sanitizasyonu atladıktan sonra, değer geçersizse, Angular2 sessizce onu yok sayar.
David Pfeffer

NgStyle yapmalısınız ve sanitasyonla uğraşmadan çalışacaktır.
yglodt

Benim için Angular8'de çalıştı. Sanitasyonun en iyisi olduğunu düşünüyorum ... bunun bir nedeni var. @yglodt.
Sean Salonları

67

Bunu kullanın, bu <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>benim için sorunu çözdü.


Güvenli ve basit.
Kenmore

Nazik sözleriniz için teşekkürler @ Kenmore. Yardımcı olabileceğime sevindim. Şerefe.
iRedia Ebikade

@ Sammy-RogersGeek aynı kodu Image etiketine yazabilir miyim?
Arjun

Günümü kurtardın!
VAdaihiep

Duygusal. Teşekkür ederim.
Mindsect Ekibi

52

Doğrusal gradyanlı arka plan resmi ( *ngFor) ise

Görünüm:

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

Sınıf:

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
günümü kurtardın
Thamaraiselvam

1
Mükemmel çalışıyor :))
Abhijit Srivastava

@AbhijitSrivastava thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url yazdım ($ {thumbnail}) )ve [style.backgroundImage]="thumbnailMediumIcon". Hangi Angular sürümünü kullandınız? Arka plan resmini de denedim. Bu hala çalışıyor mu? Diğer yaklaşımı sevmedim mi?
MTZ

1
@AbhijitSrivastava Teşekkürler! thumbnail
MTZ

1
getBackgroundGörünümün içini aramanız tavsiye edilmez çünkü Angular, bypassSecurityTrustStylegörünüm her yenilendiğinde arama yapmak zorundadır . Bunu test etmek için, içine console.log ekleyin getBackgroundve bu işlevin her tıklama veya kullanıcı kaydırma olayında çağrıldığını göreceksiniz
Marcin

9

Angular2 için bu kullanışlı boruyu kontrol edin : Kullanım:

  1. içerisinde SafePipekod yerine DomSanitizationServiceileDomSanitizer

  2. sağlamak SafePipeeğer seninNgModule

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


8

Https://angular.io/api/platform-browser/DomSanitizer adresindeki belgelere göre, bunu yapmanın doğru yolu sanitize kullanmak gibi görünüyor. En azından Angular 7'de (bunun daha önce değişip değişmediğini bilmiyorum). Bu benim için çalıştı:

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, bkz. Https://angular.io/api/core/SecurityContext . Temelde sadece bu enum:

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

1
Bu en güncel cevap. Ayrıca this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
kısaltılabilir

@Zahema Bunun verilen cevaba denk olduğuna inanmıyorum. bypassSecurityTrustStylegüvenliği sanitize(SecurityContext.STYLE, style)güçlendirirken güvenliği yok sayar . sanitizeUygun olanı kullanmanızı tavsiye ederim SecurityContext.
Oscar

@Zahema bypassSecurityTrustStyle, içinde erişilemeyen (en azından yapamadım) bir Nesne döndürüyor [ngStyle]. sanitize(SecurityContext.STYLE, style)bunun yerine düz bir dize döndürür.
Alexander Fink

@Oscar Katılıyorum ama nedense tüm senaryolarda beklendiği gibi çalışmıyor. bypassSecurityTrustStyletemelde onu zorlamaktır.
Zahema

6

Angular 7'de Image tag'e dinamik url eklerken aynı sorunu yaşadım. Çok aradım ve bu çözümü buldum.

Öncelikle, bileşen dosyasında aşağıdaki kodu yazın.

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

Artık html resim etiketinize şöyle yazabilirsiniz.

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

İtem.imageUrl yerine ihtiyacınıza göre yazabilirsiniz.

Bu siteden bir referans aldım. dinamik url'ler . Umarım bu çözüm size yardımcı olur :)


resimler için işe yarıyor, ancak soru, bu yanıtın ilgisiz olduğu, arka plan resmi olarak kullanılan URL tarzıyla
ilgiliydi

3

Bu uyarıyı yalnızca gerçekten dezenfekte edilmiş bir şey varsa yazdırmak için açık bir sorun var: https://github.com/angular/angular/pull/10272

Hiçbir şey sterilize edilmediğinde bu uyarı basıldığında ayrıntılı olarak okumadım.


3
Buraya gelebilecekler için: bu sorun çözüldü. Her zaman değil, yalnızca HTML'yi temizlediyse uyarısını yazdırır.
flamusdiu

Bunu yapmanın yanlış bir uygulama olduğunu bilmek istedim. Bu uyarıyı almamaya çalışmalı mıyım?
Amrit

Bunu kullanıcı tarafından sağlanan içeriğe (bir giriş alanından gelen metin veya bir veritabanından veya kontrol etmediğiniz diğer kaynaklardan yüklenen kullanıcı içeriği gibi) uygularken çok dikkatli olmalısınız. Bu şekilde Angular'a, doğası gereği güvenli olmayan içeriğin şu şekilde ele alınması gerektiğini söylersiniz: Sabitler, derleme sırasında aktarılan ortam değişkenleri, yalnızca bu tür güvenli değerlerden hesaplanan değerler gibi kontrol ettiğiniz statik içerik için kullanmak tamamen iyidir.
Günter Zöchbauer

1

Uyarının size önerdiği şeyi zaten yapan herkes için, Angular 5'e yükseltmeden önce, SafeStyletürlerimi stringşablonlarda kullanmadan önce eşlemeliydim. Angular 5'ten sonra artık durum böyle değil. Bir image: SafeStyleyerine sahip olmak için modellerimi değiştirmek zorunda kaldım image: string. Zaten [style.background-image]özellik bağlamayı kullanıyordum ve tüm url'de güvenliği atlıyordum.

Umarım bu birine yardımcı olur.


0

Angular, özel bir sterilizasyon kütüphanesi olmadığından, herhangi bir risk almamak için şüpheli içeriğe aşırı heveslidir. Temizlemeyi özel bir kitaplığa, örneğin DOMPurify'a devredebilirsiniz. İşte DOMPurify with Angular'ı kolayca kullanmak için yaptığım bir sarmalayıcı kitaplığı.

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

HTML'yi bildirimsel olarak sterilize etmek için bir borusu vardır:

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

Unutulmaması gereken bir nokta DOMPurify'ın HTML / SVG'yi temizlemek için harikadır, ancak CSS değildir. Böylece, CSS'yi işlemek için Angular'ın CSS temizleyicisini sağlayabilirsiniz:

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

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

Bu dahili - yüksek ɵönek, ancak Angular ekibi bunu kendi paketlerinde de böyle kullanıyor.


-1

Benim durumumda, görüntü bileşenine gitmeden önce görselin URL'sini aldım ve arka plan görüntüsü olarak kullanmak istiyorum, bu yüzden bu URL'yi kullanmak için Angular'a güvenli ve kullanılabilir olduğunu söylemeliyim.

.Ts dosyasında

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

.Html dosyasında

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

Lütfen cevabınızı açıklamak için düzenleyin ve neden mevcut cevaplardan daha iyi bir cevap olduğunu not edin.
Dragonthoughts
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.