WARNUNG: Desinfizieren der URL für unsichere Stilwerte


107

Ich möchte das Hintergrundbild eines DIV in einer Komponentenvorlage in meiner Angular 2-App festlegen. Ich erhalte jedoch immer wieder die folgende Warnung in meiner Konsole und erhalte nicht den gewünschten Effekt ... Ich bin mir nicht sicher, ob das dynamische CSS-Hintergrundbild aufgrund von Sicherheitsbeschränkungen in Angular2 blockiert wird oder ob meine HTML-Vorlage beschädigt ist.

Dies ist die Warnung, die ich in meiner Konsole sehe (ich habe meine IMG-URL geändert in /img/path/is/correct.png:

WARNUNG: Bereinigen der URL eines unsicheren Stilwerts (SafeValue muss [property] = binding: /img/path/is/correct.png verwenden (siehe http://g.co/ng/security#xss )) (siehe http: // g.co/ng/security#xss ).

Die Sache ist, dass ich mit dem DomSanitizationServicein Angular2 bereinige, was in meine Vorlage injiziert wird. Hier ist mein HTML, das ich in meiner Vorlage habe:

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

Hier ist die Komponente ...

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

            }
        }
    }
}

Bitte beachten Sie, dass, wenn ich gerade mit [src] = "image" an die Vorlage gebunden habe, zum Beispiel:

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

und imagewurde mit bypassSecurityTrustUrlallem bestanden, schien gut zu funktionieren ... kann jemand sehen, was ich falsch mache?


Haben Sie eine Lösung für Ihre Frage erhalten? Ich habe genau das gleiche Problem und versuche immer noch, eine Lösung zu finden. Danke im Voraus!
SK.

Antworten:


112

Sie müssen die gesamte urlAnweisung in Folgendes einschließen bypassSecurityTrustStyle:

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

Und haben

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

Andernfalls wird es nicht als gültige Stileigenschaft angesehen


1
PierreDuc, irgendwelche Weisheitswörter, wenn das Hintergrundbild wie oben umgangen wird, aber Angular2 es dann stillschweigend ignoriert? Ich kann eine neue Frage stellen, aber ich denke, dass Ihre Antwort ziemlich wichtig ist.
David Pfeffer

@ DavidPfeffer Es ist schwierig zu beurteilen, wo Dinge schief gehen, ohne einen Code zu sehen :) Ich verwende diesen Code in der neuesten Angular2 und es funktioniert immer noch ..
Poul Kruijt

1
Ich habe es herausgefunden. Nachdem Sie die Bereinigung umgangen haben und der Wert ungültig ist, ignoriert Angular2 ihn stillschweigend.
David Pfeffer

Sie sollten ngStyle und es wird einfach funktionieren, ohne die Desinfektion zu beeinträchtigen.
Yglodt

Arbeitete für mich in Angular8. Ich denke, dass Desinfektion am besten ist ... es gibt sie aus einem Grund. @yglodt.
Sean Halls

66

Verwenden Sie dies, um <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>das Problem für mich zu lösen.


Sicher und einfach.
Kenmore

Vielen Dank für Ihre freundlichen Worte @ Kenmore. Ich bin froh, dass ich helfen konnte. Prost.
iRedia Ebikade

@ Sammy-RogersGeek Kann ich denselben Code in das Image-Tag schreiben?
Arjun

Du rettest meinen Tag!
VAdaihiep

Beredt. Danke dir.
Mindsect Team

52

Wenn Hintergrundbild mit linearem Farbverlauf ( *ngFor)

Aussicht:

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

Klasse:

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
Du hast meinen Tag gerettet
Thamaraiselvam

1
Funktioniert perfekt :))
Abhijit Srivastava

@AbhijitSrivastava Ich schrieb thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(URL ($ {thumbnail}) )und [style.backgroundImage]="thumbnailMediumIcon". Welche Angular-Version haben Sie verwendet? Ich habe auch versucht, Hintergrundbild. Funktioniert das noch Ich mag den anderen Ansatz nicht?
MTZ

1
@AbhijitSrivastava Danke! Mein Fehler, ich habe einen Blob ( thumbnail) anstelle einer URL übergeben
MTZ

1
Es wird nicht empfohlen, getBackgroundinnerhalb der Ansicht aufzurufen , da Angular bypassSecurityTrustStylejedes Mal aufrufen muss, wenn diese Ansicht aktualisiert wird. Um dies zu testen, fügen Sie console.log hinzu getBackgroundund Sie werden sehen, dass die Funktion bei jedem Klick oder Benutzer-Scroll-Ereignis aufgerufen wird
Marcin

9

Überprüfen Sie dieses handliche Rohr auf Angular2: Verwendung:

  1. in dem SafePipeCode, ersetzen DomSanitizationServicemitDomSanitizer

  2. Geben Sie das an, SafePipewenn IhrNgModule

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


8

Basierend auf den Dokumenten unter https://angular.io/api/platform-browser/DomSanitizer scheint der richtige Weg, dies zu tun, die Verwendung von sanitize zu sein. Zumindest in Angular 7 (weiß nicht, ob sich dies gegenüber zuvor geändert hat). Das hat bei mir funktioniert:

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

Zu SecurityContext siehe https://angular.io/api/core/SecurityContext . Im Grunde ist es nur diese Aufzählung:

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

1
Dies ist die aktuellste Antwort. Es kann auch kurzgeschlossen werden:this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema

@ Zahema Ich glaube nicht, dass dies der Antwort entspricht. bypassSecurityTrustStyleignoriert die Sicherheit und sanitize(SecurityContext.STYLE, style)erhöht die Sicherheit. Ich würde empfehlen, sanitizemit dem entsprechenden zu verwenden SecurityContext.
Oscar

@Zahema bypassSecurityTrustStylegibt ein Objekt zurück, auf das nicht zugegriffen werden kann (zumindest konnte ich es nicht tun) [ngStyle]. sanitize(SecurityContext.STYLE, style)Gibt stattdessen eine einfache Zeichenfolge zurück.
Alexander Fink

@Oscar Ich stimme zu, aber aus irgendeinem Grund funktioniert es nicht immer wie erwartet in allen Szenarien. bypassSecurityTrustStyleist im Grunde brutal es zu erzwingen.
Zahema

6

Ich habe das gleiche Problem beim Hinzufügen einer dynamischen URL im Image-Tag in Angular 7 erhalten. Ich habe viel gesucht und diese Lösung gefunden.

Schreiben Sie zunächst den folgenden Code in die Komponentendatei.

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

Jetzt können Sie in Ihrem HTML-Bild-Tag so schreiben.

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

Sie können gemäß Ihren Anforderungen anstelle von item.imageUrl schreiben

Ich habe eine Referenz von dieser Seite bekommen. dynamische URLs . Hoffe diese Lösung wird dir helfen :)


Es funktioniert für Bilder, aber die Frage
betraf die

3

Es gibt ein offenes Problem, bei dem diese Warnung nur gedruckt werden kann, wenn tatsächlich etwas bereinigt wurde: https://github.com/angular/angular/pull/10272

Ich habe nicht im Detail gelesen, wann diese Warnung gedruckt wurde, als nichts bereinigt wurde.


3
Für diejenigen, die hierher kommen könnten: Dieses Problem wurde behoben. Die Warnung wird nur gedruckt, wenn HTML bereinigt wurde, und nicht immer.
Flamusdiu

Ich wollte wissen, ob es falsch ist, dies zu tun. Sollte ich versuchen, diese Warnung nicht zu erhalten?
Amrit

Sie sollten sehr vorsichtig sein, wenn Sie dies auf vom Benutzer bereitgestellte Inhalte anwenden (z. B. Text aus einem Eingabefeld oder Benutzerinhalte, die aus einer Datenbank oder anderen Quellen geladen wurden, die Sie nicht kontrollieren. Auf diese Weise teilen Sie Angular mit, dass von Natur aus unsichere Inhalte behandelt werden sollen Es ist jedoch völlig in Ordnung, es für statische Inhalte zu verwenden, die Sie steuern, wie Konstanten, Umgebungsvariablen, die zur Erstellungszeit übergeben wurden, Werte, die nur aus solchen sicheren Werten berechnet wurden.
Günter Zöchbauer

1

Für alle, die bereits das tun, was die Warnung vorschlägt, musste ich vor dem Upgrade auf Angular 5 meine SafeStyleTypen zuordnen, bevor ich stringsie in den Vorlagen verwenden konnte. Nach Angular 5 ist dies nicht mehr der Fall. Ich musste meine Modelle ändern, um eine image: SafeStylestatt zu haben image: string. Ich habe bereits die [style.background-image]Eigenschaftsbindung verwendet und die Sicherheit für die gesamte URL umgangen.

Hoffe das hilft jemandem.


0

Da Angular keine dedizierte Desinfektionsbibliothek ist, ist es gegenüber verdächtigen Inhalten übereifrig, kein Risiko einzugehen. Sie können die Bereinigung an eine dedizierte Bibliothek delegieren, z. B. DOMPurify. Hier ist eine Wrapper-Bibliothek, die ich erstellt habe, um DOMPurify mit Angular einfach zu verwenden.

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

Es hat eine Pipe, um HTML deklarativ zu bereinigen:

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

Eine Sache, die Sie beachten sollten, ist, dass DOMPurify sich hervorragend zum Bereinigen von HTML / SVG eignet, nicht jedoch von CSS. So können Sie Angulars CSS-Desinfektionsmittel für CSS bereitstellen:

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

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

Es ist ein internes ɵPräfix - hense , aber so verwendet es das Angular-Team sowieso auch für seine eigenen Pakete.


-1

In meinem Fall habe ich die Bild-URL erhalten, bevor ich zur Anzeigekomponente gelangt bin, und möchte sie als Hintergrundbild verwenden. Um diese URL zu verwenden, muss ich Angular mitteilen, dass sie sicher ist und verwendet werden kann.

In der .ts-Datei

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

In der HTML-Datei

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

Bitte bearbeiten Sie Ihre Antwort, um sie zu erklären, und beachten Sie, warum sie eine bessere Antwort ist als eine der vorhandenen.
Dragon Thoughts
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.