ATTENZIONE: disinfezione dell'URL del valore di stile non sicuro


107

Voglio impostare l'immagine di sfondo di un DIV in un modello di componente nella mia app Angular 2. Tuttavia continuo a ricevere il seguente avviso nella mia console e non ottengo l'effetto desiderato ... Non sono sicuro che l'immagine di sfondo CSS dinamica sia bloccata a causa di restrizioni di sicurezza in Angular2 o se il mio modello HTML non funziona.

Questo è l'avviso che vedo nella mia console (ho cambiato il mio URL img in /img/path/is/correct.png:

AVVISO: disinfezione dell'URL del valore di stile non sicuro (SafeValue deve utilizzare [property] = binding: /img/path/is/correct.png (vedi http://g.co/ng/security#xss )) (vedi http: // g.co/ng/security#xss ).

Il fatto è che pulisco ciò che viene iniettato nel mio modello usando DomSanitizationServicein Angular2. Ecco il mio codice HTML che ho nel mio modello:

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

Ecco il componente ...

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

            }
        }
    }
}

Tieni presente che quando mi sono limitato al modello utilizzando [src] = "image", ad esempio:

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

ed è imagestato approvato usando bypassSecurityTrustUrltutto sembrava funzionare bene ... qualcuno può vedere cosa sto facendo di sbagliato?


Hai trovato la soluzione alla tua domanda. Ho esattamente lo stesso problema e sto ancora cercando di trovare una soluzione. Grazie in anticipo!
SK.

Risposte:


112

Devi racchiudere l'intera urlaffermazione in bypassSecurityTrustStyle:

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

E avere

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

Altrimenti non viene visto come una proprietà di stile valida


1
PierreDuc, qualche parola di saggezza per quando l'immagine di sfondo È aggirata come sopra, ma poi Angular2 la ignora silenziosamente? Posso pubblicare una nuova domanda ma penso che sia abbastanza pertinente alla tua risposta.
David Pfeffer

@DavidPfeffer È difficile giudicare dove le cose vanno storte senza vedere alcun codice :) Uso questo codice nell'ultimo angular2 e funziona ancora ..
Poul Kruijt

1
L'avevo capito. Dopo aver ignorato la sanificazione, se il valore non è valido, Angular2 lo ignora silenziosamente.
David Pfeffer

Dovresti ngStyle e funzionerà senza problemi con la sanificazione.
yglodt

Ha lavorato per me in Angular8. Penso che la sanificazione sia la cosa migliore ... esiste per un motivo. @yglodt.
Sean Halls il

67

Usa questo per <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>risolvere il problema per me.


Sicuro e semplice.
Kenmore

Grazie per le tue gentili parole @ Kenmore. Sono contento di poter essere d'aiuto. Saluti.
iRedia Ebikade

@ Sammy-RogersGeek posso scrivere lo stesso codice nel tag immagine?
Arjun

Mi salvi la giornata!
VAdaihiep

Eloquente. Grazie.
Mindsect Team

52

Se l'immagine di sfondo con gradiente lineare ( *ngFor)

Visualizza:

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

Classe:

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
mi hai salvato la giornata
Thamaraiselvam

1
Funziona perfettamente :))
Abhijit Srivastava

@AbhijitSrivastava Ho scritto thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url ($ {thumbnail}) )e [style.backgroundImage]="thumbnailMediumIcon". Quale versione angolare hai usato? Ho anche provato l'immagine di sfondo. Funziona ancora? Non mi piace l'altro approccio?
MTZ

1
@AbhijitSrivastava Thanks! Errore mio, ho passato un blob ( thumbnail) invece di un URL
MTZ

1
Non è consigliabile chiamare getBackgroundall'interno della vista, perché Angular deve chiamare bypassSecurityTrustStyleogni volta che la vista viene aggiornata. Per testarlo aggiungi console.log all'interno getBackgrounde vedrai che la funzione viene chiamata ad ogni clic o evento di scorrimento dell'utente
Marcin

9

Controlla questo pratico tubo per Angular2: Utilizzo:

  1. nel SafePipecodice, sostituire DomSanitizationServiceconDomSanitizer

  2. fornire il SafePipese il tuoNgModule

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


8

Sulla base dei documenti su https://angular.io/api/platform-browser/DomSanitizer , il modo giusto per farlo sembra essere usare sanitize. Almeno in Angular 7 (non so se è cambiato da prima). Questo ha funzionato per me:

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

Per quanto riguarda SecurityContext, vedere https://angular.io/api/core/SecurityContext . Fondamentalmente è solo questa enumerazione:

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

1
Questa è la risposta più aggiornata. Può essere anche accorciato:this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema

@Zahema Non credo che sia equivalente alla risposta fornita. bypassSecurityTrustStyleignora la sicurezza mentre sanitize(SecurityContext.STYLE, style)rafforza la sicurezza. Consiglierei di utilizzare sanitizecon l'appropriato SecurityContext.
Oscar

@Zahema bypassSecurityTrustStylerestituisce un oggetto a cui non è possibile accedere (almeno non potevo farlo) in [ngStyle]. sanitize(SecurityContext.STYLE, style)restituisce invece una semplice stringa.
Alexander Fink,

@Oscar Sono d'accordo ma per qualche motivo non sempre funziona come previsto in tutti gli scenari. bypassSecurityTrustStyleè fondamentalmente brutale costringerlo.
Zahema

6

Ho riscontrato lo stesso problema durante l'aggiunta dell'URL dinamico nel tag immagine in Angular 7. Ho cercato molto e ho trovato questa soluzione.

Per prima cosa, scrivi sotto il codice nel file del componente.

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

Ora nel tuo tag immagine html, puoi scrivere in questo modo.

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

Puoi scrivere secondo le tue esigenze invece di item.imageUrl

Ho ricevuto un riferimento da questo sito. URL dinamici . Spero che questa soluzione ti aiuti :)


funziona per le immagini, ma la domanda riguardava l'URL in stile, utilizzando come immagine di sfondo, la cui risposta non è correlata
Amirreza

3

C'è un problema aperto per stampare questo avviso solo se c'era effettivamente qualcosa di disinfettato: https://github.com/angular/angular/pull/10272

Non ho letto in dettaglio quando viene stampato questo avviso quando nulla è stato disinfettato.


3
Per quelli che potrebbero venire qui: quel problema è stato risolto. Stampa l'avviso solo SE ha disinfettato l'HTML e non sempre.
flamusdiu

Volevo sapere se è una pratica sbagliata farlo? Dovrei provare a non ricevere questo avviso?
Amrit

Dovresti essere molto cauto quando applichi questo al contenuto fornito dall'utente (come il testo da un campo di input o il contenuto dell'utente caricato da un database o altre fonti che non controlli. In questo modo dici ad Angular che i contenuti intrinsecamente non sicuri dovrebbero essere trattati come affidabile. Va benissimo usarlo per contenuti statici che controlli, come costanti, variabili di ambiente passate al momento della compilazione, valori calcolati solo da tali valori sicuri.
Günter Zöchbauer

1

Per chiunque stia già facendo ciò che l'avviso suggerisce di fare, prima dell'aggiornamento ad Angular 5, dovevo mappare i miei SafeStyletipi stringprima di utilizzarli nei modelli. Dopo Angular 5, non è più così. Ho dovuto cambiare i miei modelli per avere un al image: SafeStyleposto di image: string. Stavo già usando l' [style.background-image]associazione della proprietà e bypassando la sicurezza sull'intero URL.

Spero che questo aiuti qualcuno.


0

Poiché Angular non è una libreria di sanificazione dedicata, è troppo zelante nei confronti dei contenuti sospetti per non correre alcun rischio. Puoi delegare la sanificazione a una libreria dedicata, ad esempio DOMPurify. Ecco una libreria wrapper che ho creato per utilizzare facilmente DOMPurify con Angular.

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

Ha una pipe per disinfettare in modo dichiarativo l'HTML:

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

Una cosa da tenere a mente è che DOMPurify è ottimo per disinfettare HTML / SVG, ma non CSS. Quindi puoi fornire il disinfettante CSS di Angular per gestire i CSS:

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

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

È interno - ɵprefisso hense , ma è così che il team di Angular lo utilizza anche nei propri pacchetti.


-1

Nel mio caso, ho ottenuto l'URL dell'immagine prima di arrivare al componente di visualizzazione e voglio usarlo come immagine di sfondo, quindi per usare quell'URL devo dire ad Angular che è sicuro e può essere utilizzato.

Nel file .ts

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

Nel file .html

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

Modifica la tua risposta per spiegarla e nota perché è una risposta migliore di tutte quelle esistenti.
Pensieri del drago
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.