CẢNH BÁO: khử trùng url giá trị kiểu không an toàn


107

Tôi muốn đặt hình nền của DIV trong Mẫu thành phần trong ứng dụng Angular 2 của mình. Tuy nhiên, tôi tiếp tục nhận được cảnh báo sau trong bảng điều khiển của mình và tôi không nhận được hiệu quả mong muốn ... Tôi không chắc liệu hình nền CSS động có đang bị chặn do các hạn chế bảo mật trong Angular2 hay không hoặc nếu mẫu HTML của tôi bị hỏng.

Đây là cảnh báo tôi thấy trong bảng điều khiển của mình (Tôi đã thay đổi url img của mình thành /img/path/is/correct.png:

CẢNH BÁO: khử trùng url giá trị kiểu không an toàn (SafeValue phải sử dụng [property] = binding: /img/path/is/correct.png (xem http://g.co/ng/security#xss )) (xem http: // g.co/ng/security#xss ).

Vấn đề là tôi làm vệ sinh những gì được tiêm vào mẫu của tôi bằng cách sử dụng DomSanitizationServicetrong Angular2. Đây là HTML của tôi mà tôi có trong mẫu của mình:

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

Đây là thành phần ...

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

            }
        }
    }
}

Xin lưu ý rằng khi tôi chỉ liên kết với mẫu bằng [src] = "image", ví dụ:

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

imageđã được thông qua bằng cách sử dụng bypassSecurityTrustUrlmọi thứ dường như hoạt động tốt ... bất cứ ai có thể thấy những gì tôi đang làm sai?


Bạn đã nhận được giải pháp cho câu hỏi của bạn. Tôi gặp chính xác vấn đề tương tự và vẫn đang cố gắng tìm giải pháp. Cảm ơn trước!
SK.

Câu trả lời:


112

Bạn phải gói toàn bộ urlcâu lệnh trong bypassSecurityTrustStyle:

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

Và có

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

Nếu không, nó không được coi là thuộc tính kiểu hợp lệ


1
PierreDuc, có lời nào khôn ngoan khi hình nền IS bỏ qua như trên, nhưng sau đó Angular2 lại im lặng bỏ qua? Tôi có thể đăng một câu hỏi mới nhưng tôi nghĩ câu trả lời của bạn khá là vi phạm.
David Pfeffer

@DavidPfeffer Thật khó để phán xét nơi mà mọi thứ đi sai mà không nhìn thấy bất kỳ mã :) Tôi sử dụng mã này trong angular2 mới nhất và nó vẫn còn làm việc ..
Poul Kruijt

1
Tôi đã hiểu rồi. Sau khi bạn bỏ qua quá trình khử trùng, nếu giá trị không hợp lệ, Angular2 sẽ âm thầm bỏ qua nó.
David Pfeffer

Bạn nên ngStyle và nó sẽ hoạt động mà không cần phải làm vệ sinh.
yglodt

Đã làm việc cho tôi trong Angular8. Tôi nghĩ rằng vệ sinh là tốt nhất ... nó tồn tại là có lý do. @yglodt.
Sean Halls

67

Sử dụng điều <div [ngStyle]="{'background-image':'url('+imageUrl+')'}"></div>này giải quyết vấn đề cho tôi.


An toàn và đơn giản.
Kenmore

Cảm ơn những lời tốt đẹp của bạn @Kenmore. Tôi rất vui vì tôi có thể được giúp đỡ. Chúc mừng.
iRedia Ebikade 17/02/19

@ Sammy-RogersGeek Tôi có thể viết mã tương tự trong thẻ Hình ảnh không?
Arjun

Bạn tiết kiệm ngày của tôi!
VAdaihiep 19/07/19

Hùng biện. Cảm ơn bạn.
Nhóm Mindsect

52

Nếu hình nền có gradient tuyến tính ( *ngFor)

Lượt xem:

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

Lớp học:

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
bạn đã lưu trong ngày của tôi
Thamaraiselvam

1
Hoạt động hoàn hảo :))
Abhijit Srivastava

@AbhijitSrivastava Tôi đã viết thumbnailMediumIcon = this.sanitizer.bypassSecurityTrustUrl(url ($ {thumbnail}) )[style.backgroundImage]="thumbnailMediumIcon". Bạn đã sử dụng phiên bản Angular nào? Tôi cũng đã thử hình nền. Cái này vẫn hoạt động chứ? Tôi không thích cách tiếp cận khác?
MTZ

1
@AbhijitSrivastava Cảm ơn! Sai lầm của tôi, tôi đã chuyển một blob ( thumbnail) thay vì một URL
MTZ

1
Bạn không nên gọi getBackgroundbên trong dạng xem, vì Angular phải gọi bypassSecurityTrustStylemỗi lần dạng xem đó được làm mới. Để thử nghiệm thêm bên console.log getBackgroundvà bạn sẽ thấy chức năng đó được gọi là cho mỗi nhấp chuột hoặc sử dụng cuộn sự kiện
Marcin

9

Kiểm tra đường ống tiện dụng này cho Angular2:

  1. trong SafePipemã, thay thế DomSanitizationServicebằngDomSanitizer

  2. cung cấp SafePipenếu của bạnNgModule

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


8

Dựa trên tài liệu tại https://angular.io/api/platform-browser/DomSanitizer , cách thích hợp để thực hiện việc này dường như là sử dụng sanitize. Ít nhất là trong Angular 7 (không biết điều này có thay đổi so với trước đây không). Điều này đã làm việc cho tôi:

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, xem https://angular.io/api/core/SecurityContext . Về cơ bản nó chỉ là enum này:

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

1
Đây là câu trả lời cập nhật nhất. Nó có thể được shortned quá:this.sanitizer.bypassSecurityTrustStyle(`url('${this.image} ')`);
Zahema

@Zahema Tôi không tin rằng điều đó tương đương với câu trả lời được cung cấp. bypassSecurityTrustStylebỏ qua bảo mật trong khi sanitize(SecurityContext.STYLE, style)củng cố bảo mật. Tôi muốn giới thiệu sử dụng sanitizevới thích hợp SecurityContext.
Oscar

@Zahema bypassSecurityTrustStyletrả về một Đối tượng không thể được truy cập (ít nhất là tôi không thể làm điều đó) trong [ngStyle]. sanitize(SecurityContext.STYLE, style)thay vào đó trả về một chuỗi đơn giản.
Alexander Fink

@Oscar Tôi đồng ý nhưng vì một số lý do mà nó không phải lúc nào cũng hoạt động như mong đợi trong tất cả các trường hợp. bypassSecurityTrustStylevề cơ bản là vũ phu buộc nó.
Zahema

6

Tôi gặp vấn đề tương tự khi thêm url động trong thẻ Image trong Angular 7. Tôi đã tìm kiếm rất nhiều và tìm thấy giải pháp này.

Đầu tiên, viết mã dưới đây trong tệp thành phần.

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

Bây giờ trong thẻ hình ảnh html của bạn, bạn có thể viết như thế này.

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

Bạn có thể viết theo yêu cầu của mình thay vì item.imageUrl

Tôi có một tài liệu tham khảo từ trang web này. url động . Hy vọng giải pháp này sẽ giúp bạn :)


nó hoạt động cho hình ảnh, nhưng câu hỏi là về URL trong phong cách, sử dụng như hình nền, mà câu trả lời này là không liên quan
Amirreza

3

Có một vấn đề mở là chỉ in cảnh báo này nếu thực sự có thứ gì đó đã được khử trùng: https://github.com/angular/angular/pull/10272

Tôi đã không đọc chi tiết cảnh báo này được in khi không có gì được làm sạch.


3
Đối với những người có thể đến đây: vấn đề đó đã được giải quyết. Nó chỉ in cảnh báo NẾU nó đã làm sạch HTML chứ không phải mọi lúc.
flamusdiu

Tôi muốn biết làm như vậy có sai thực tế không? Tôi có nên cố gắng không nhận được cảnh báo này không?
Amrit

Bạn nên rất thận trọng khi bạn áp dụng điều này để nội dung do người dùng cung cấp (như văn bản từ một lĩnh vực đầu vào hoặc sử dụng nội dung được tải từ một cơ sở dữ liệu hoặc các nguồn khác mà bạn không kiểm soát được. Bằng cách này bạn nói với góc mà nội dung vốn đã không an toàn phải được coi là . trustworty nó hoàn toàn tốt đẹp mặc dù sử dụng nó cho nội dung tĩnh mà bạn kiểm soát, như hằng, biến môi trường thông qua tại thời gian xây dựng, giá trị tính toán chỉ từ các giá trị an toàn như vậy.
Günter Zöchbauer

1

Đối với bất kỳ ai đang làm những gì cảnh báo đề xuất bạn làm, trước khi nâng cấp lên Angular 5, tôi đã phải lập bản đồ SafeStylecác loại của mìnhstring trước khi sử dụng chúng trong các mẫu. Sau Angular 5, điều này không còn xảy ra nữa. Tôi đã phải thay đổi mô hình của mình để có một image: SafeStylethay thế image: string. Tôi đã sử dụng [style.background-image]ràng buộc thuộc tính và bỏ qua bảo mật trên toàn bộ url.

Hy vọng điều này sẽ giúp ai đó.


0

Vì Angular không phải là một thư viện làm vệ sinh chuyên dụng, nên việc không chấp nhận bất kỳ rủi ro nào là quá cẩn trọng đối với nội dung đáng ngờ. Ví dụ, bạn có thể ủy quyền việc khử trùng cho một thư viện chuyên dụng - DOMPurify. Đây là thư viện trình bao bọc mà tôi đã tạo để dễ dàng sử dụng DOMPurify với Angular.

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

Nó có một đường ống để khử trùng HTML một cách khai báo:

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

Một điều cần lưu ý là DOMPurify rất tốt để khử trùng HTML / SVG, nhưng không phải CSS. Vì vậy, bạn có thể cung cấp trình vệ sinh CSS của Angular để xử lý CSS:

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

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

Đó là ɵtiền tố nội bộ - hense , nhưng dù sao đây cũng là cách nhóm Angular sử dụng nó trên các gói của riêng họ.


-1

Trong trường hợp của tôi, tôi có URL hình ảnh trước khi đến thành phần hiển thị và muốn sử dụng nó làm hình nền, vì vậy để sử dụng URL đó, tôi phải nói với Angular rằng nó an toàn và có thể được sử dụng.

Trong tệp .ts

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

Trong tệp .html

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

Vui lòng chỉnh sửa câu trả lời của bạn để giải thích nó và lưu ý lý do tại sao nó là một câu trả lời tốt hơn bất kỳ câu nào hiện có.
Dragonthoughts
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.