ПОПЕРЕДЖЕННЯ: оздоровлення URL-адреси небезпечного стилю


107

Я хочу встановити фонове зображення DIV у шаблоні компонентів у своїй програмі Angular 2. Однак на консолі я отримую таке попередження, і я не отримую бажаного ефекту ... Я не впевнений, що динамічне фонове зображення CSS блокується через обмеження безпеки в Angular2 або якщо мій шаблон HTML порушений.

Це попередження, яке я бачу на своїй консолі (я змінив URL-адресу img на /img/path/is/correct.png:

ПОПЕРЕДЖЕННЯ: санітарія URL-адреси небезпечного стилю (SafeValue повинен використовувати [властивість] = прив'язка: /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все, здавалося, працює добре ... може хтось бачить, що я роблю неправильно?


Ви отримали рішення свого питання. У мене саме таке питання і досі намагаюся знайти рішення. Спасибі заздалегідь!
СК.

Відповіді:


112

Ви повинні загортати весь urlвислів у bypassSecurityTrustStyle:

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

І мати

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

В іншому випадку він не розглядається як дійсне властивість стилю


1
П'єрдук, будь-які слова мудрості, коли фонове зображення обходить як вище, але тоді Angular2 мовчки ігнорує це? Я можу поставити нове запитання, але я думаю, що це досить відповідає вашій відповіді.
Девід Пфеффер

@DavidPfeffer Важко судити, де все піде не так, не бачачи жодного коду :) Я використовую цей код в останньому angular2 і він все ще працює ..
Poul Kruijt

1
Я зрозумів це. Після обходу санітарії, якщо значення недійсне, Angular2 мовчки ігнорує його.
Девід Пфеффер

Вам слід ngStyle, і він буде просто працювати, не псуючи санітарну обробку.
yglodt

Працював для мене в Angular8. Я вважаю, що санітарно-гігієнічна робота найкраща ... вона існує з причини. @yglodt
Шон Холл

67

Використовувати це <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>це вирішило проблему для мене.


Безпечний і простий.
Кенмор

Дякую за добрі слова @Kenmore. Я радий, що можу допомогти. Ура.
iRedia Ebikade

@ Sammy-RogersGeek чи можу я написати те саме код у тезі Image?
Арджун

Ти врятуєш мій день!
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
ти врятував мій день
Тамарайсельвам

1
Працює чудово :))
Abhijit Srivastava

@AbhijitSrivastava Я написав thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(URL ($ {thumbnail}) )і [style.backgroundImage]="thumbnailMediumIcon". Яку кутову версію ви використовували? Я також спробував фонове зображення. Це все ще працює? Мені не подобається інший підхід?
МТЗ

1
@AbhijitSrivastava Дякую! Моя помилка, я передав крапку ( thumbnail) замість URL
MTZ

1
Не рекомендується дзвонити getBackgroundвсередині перегляду, оскільки Angular повинен дзвонити bypassSecurityTrustStyleкожен раз, коли цей погляд оновлюється. Щоб перевірити додавання console.log всередині, getBackgroundви побачите, що функція викликається при кожному натисканні або події прокрутки користувача
Marcin

9

Перевірте цю зручну трубу на Angular2: Використання:

  1. у SafePipeкоді замінити DomSanitizationServiceнаDomSanitizer

  2. надайте, SafePipeякщо вашNgModule

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


8

На основі документів на веб- сайті https://angular.io/api/platform-browser/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
Це найсучасніша відповідь. Це може бути також this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
коротко

@Zahema Я не вірю, що це рівнозначно наданій відповіді. bypassSecurityTrustStyleігнорує безпеку, а sanitize(SecurityContext.STYLE, style)підсилює безпеку. Я б рекомендував використовувати sanitizeз відповідним SecurityContext.
Оскар

@Zahema bypassSecurityTrustStyleповертає Об'єкт, до якого не можна отримати доступ (принаймні, я не міг цього зробити) в [ngStyle]. sanitize(SecurityContext.STYLE, style)натомість повертає просту рядок.
Олександр Фінк

@Oscar Я згоден, але чомусь це не завжди працює так, як очікувалося у всіх сценаріях. bypassSecurityTrustStyleв основному грубо змушує це.
Захема

6

У мене виникла та сама проблема, додаючи динамічний URL в тег Image в кутовій 7. Я багато шукав і знайшов це рішення.

Спочатку напишіть код нижче у компонентний файл.

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-адреси . Сподіваюся, що це рішення допоможе вам :)


він працює для зображень, але питання
стосувалося

3

Існує відкрите питання, щоб надрукувати це попередження лише в тому випадку, якщо насправді щось було санітоване: https://github.com/angular/angular/pull/10272

Я не читав докладно, коли це попередження надруковано, коли нічого не було дезінфіковано.


3
Для тих, хто може сюди прийти: це питання було вирішено. Він роздруковує лише попередження, якщо воно не захищається HTML, а не весь час.
flamusdiu

Я хотів знати, чи це неправильна практика робити це? Чи варто намагатися не отримувати це попередження?
Amrit

Ви повинні бути дуже обережними, застосовуючи це до наданого користувачем вмісту (наприклад, тексту з поля введення чи вмісту користувача, завантаженого з бази даних чи інших джерел, якими ви не керуєте. Таким чином, ви говорите Angular, що за власне небезпечним вмістом слід трактувати як Це абсолютно чудово, хоча використовувати його для статичного вмісту, яким ви керуєте, як константи, змінні середовища, передані в час збирання, значення, обчислені лише з таких безпечних значень.
Günter Zöchbauer

1

Для всіх, хто вже робить те, що пропонує вам попередження, перед оновленням до Angular 5 мені довелося зіставити свої SafeStyleтипи, stringперш ніж використовувати їх у шаблонах. Після кутового 5 це вже не так. Мені довелося міняти свої моделі, щоб мати image: SafeStyleзамість них image: string. Я вже використовував [style.background-image]прив’язку властивостей і обходив безпеку цілої URL-адреси.

Сподіваюся, що це комусь допоможе.


0

Оскільки Angular не є спеціалізованою санітарною бібліотекою, надто підозріло ставиться до підозрілого вмісту, щоб не ризикувати. Ви можете делегувати санітарно-гігієнічні засоби до спеціальної бібліотеки, наприклад - DOMPurify. Ось бібліотека обгортки, яку я створив, щоб легко використовувати DOMPurify з Angular.

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

Він має трубу для декларативного очищення HTML:

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

Варто пам’ятати, що DOMPurify чудово підходить для очищення HTML / SVG, але не для CSS. Таким чином, ви можете запропонувати CSular для дезінфікування CSS для обробки CSS:

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

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

Це внутрішній - hense ɵпрефікс, але саме так 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>

Будь ласка, відредагуйте свою відповідь, щоб пояснити її, та зазначте, чому вона краща відповідь, ніж будь-яка з існуючих.
Драгонтаути
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.