<img>: ค่าที่ไม่ปลอดภัยที่ใช้ในบริบท URL ทรัพยากร


112

ตั้งแต่อัปเกรดเป็น Angular 2 รุ่นล่าสุดimgแท็กของฉัน:

<img class='photo-img' [hidden]="!showPhoto1" src='{{theMediaItem.photoURL1}}'>

กำลังแสดงข้อผิดพลาดของเบราว์เซอร์:

ข้อยกเว้นเดิม: ข้อผิดพลาด: ค่าที่ไม่ปลอดภัยที่ใช้ในบริบท URL ทรัพยากร

ค่าของ url คือ:

http://veeu-images.s3.amazonaws.com/media/userphotos/116_1464645173408_cdv_photo_007.jpg

แก้ไข:

ฉันได้ลองทำตามคำแนะนำในวิธีแก้ปัญหาอื่น ๆ แล้วว่าคำถามนี้ควรจะซ้ำกัน แต่ฉันได้รับข้อผิดพลาดเดียวกัน

ฉันได้เพิ่มรหัสต่อไปนี้ลงในคอนโทรลเลอร์:

import {DomSanitizationService} from '@angular/platform-browser';

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [[NavController], [App], [MenuController], [DomSanitizationService]];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;

    this.theMediaItem.photoURL1 = this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }

ฉันยังคงได้รับข้อความแสดงข้อผิดพลาดเดียวกัน

แก้ไข 2:

ฉันได้เปลี่ยน html เป็น:

<img class='photo-img' [hidden]="!showPhoto1" [src]='theMediaItem.photoURL1'>

ฉันยังคงได้รับข้อความแสดงข้อผิดพลาดเดียวกัน


ฉันไม่ชัดเจนว่าควรเปลี่ยนแปลงอะไร ฉันจะเปลี่ยน src = "{{something.else}}" เป็น [src] = "something.else" หรือไม่
Bill Noble

1
ตรง:[src]='theMediaItem.photoURL1'
GünterZöchbauer

ใช่ฉันลองแล้วและได้รับข้อความแสดงข้อผิดพลาดเดียวกัน
Bill Noble

คุณใช้ Angular2 เวอร์ชันอะไร
GünterZöchbauer

ฉันคิดว่าฉันใช้ 2.0.0-beta.15 (ฉันใช้ไอออนิกและไม่แน่ใจว่าจะตรวจสอบอย่างไร) ขออภัยสำหรับวิธีที่ฉันเพิ่มรหัสฉันไม่ชัดเจนในโปรโตคอล
Bill Noble

คำตอบ:


98

ฉันใช้ rc.4 และวิธีนี้ใช้ได้กับ ES2015 (ES6):

import {DomSanitizationService} from '@angular/platform-browser';

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [NavController, App, MenuController, DomSanitizationService];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;    
  }

  photoURL() {
    return this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }
}

ใน HTML:

<iframe [src]='photoURL()' width="640" height="360" frameborder="0"
    webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>

การใช้ฟังก์ชันจะช่วยให้มั่นใจได้ว่าค่าจะไม่เปลี่ยนแปลงหลังจากที่คุณทำความสะอาดแล้ว นอกจากนี้โปรดทราบว่าฟังก์ชันการฆ่าเชื้อที่คุณใช้ขึ้นอยู่กับบริบท

สำหรับรูปภาพbypassSecurityTrustUrlจะใช้งานได้ แต่สำหรับการใช้งานอื่น ๆ คุณต้องดูเอกสารประกอบ :

https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizer-class.html


3
"rc4" คืออะไร (และต่อมาHelzgate หมายถึง RC3 ) ฉันหมายถึงฉันจะแมปสิ่งนั้นกับเวอร์ชัน github ได้อย่างไร ทั้งใน github และ npm ฉันเห็นเฉพาะเวอร์ชันเช่น 2.4.4 หรือ 2.4.5 เท่านั้น ตอนนี้ฉันใช้ 2.4.4 และดูเหมือนว่า DomSanitizer จะเปลี่ยนไป ดังนั้นนี่คือการนำเข้าที่คุณต้องการ:import {DomSanitizer} from '@angular/platform-browser';
Red Pea

โอ้ฉันคิดของเชิงมุม GitHub สาขาจะอ้างถึง2.4.xเช่น แต่ GitHub แท็ก2.0.0-rc3จะอ้างถึงปล่อยผู้สมัครเช่น และฉันสามารถดูใน RC3DomSanitizationServiceเช่นชั้นก็ยังคงชื่อ
The Red Pea

1
this.sanitizer.bypassSecurityTrustResourceUrl(url)สำหรับวิดีโอ
Prayagupd

อ่านเอกสารอย่างละเอียดก่อนใช้สิ่งนี้: bypassSecurityTrustUrl () คำเตือน: การ เรียกวิธีนี้ด้วยข้อมูลผู้ใช้ที่ไม่น่าเชื่อถือทำให้แอปพลิเคชันของคุณเสี่ยงต่อความปลอดภัย XSS! สำหรับฉันแล้วดูเหมือนว่าจะไม่ปลอดภัยที่จะทำเช่นนั้นเว้นแต่คุณจะแน่ใจจริงๆว่าแหล่งที่มาของภาพนั้นเชื่อถือได้ แม้ว่าจะมาจากเซิร์ฟเวอร์หากผู้ใช้อัปโหลดก็สามารถใช้ประโยชน์จากโซลูชันดังกล่าวได้
เหี่ยว

147

ท่อ

// Angular
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';

/**
 * Sanitize HTML
 */
@Pipe({
  name: 'safe'
})
export class SafePipe implements PipeTransform {
  /**
   * Pipe Constructor
   *
   * @param _sanitizer: DomSanitezer
   */
  // tslint:disable-next-line
  constructor(protected _sanitizer: DomSanitizer) {
  }

  /**
   * Transform
   *
   * @param value: string
   * @param type: string
   */
  transform(value: string, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
      case 'html':
        return this._sanitizer.bypassSecurityTrustHtml(value);
      case 'style':
        return this._sanitizer.bypassSecurityTrustStyle(value);
      case 'script':
        return this._sanitizer.bypassSecurityTrustScript(value);
      case 'url':
        return this._sanitizer.bypassSecurityTrustUrl(value);
      case 'resourceUrl':
        return this._sanitizer.bypassSecurityTrustResourceUrl(value);
      default:
        return this._sanitizer.bypassSecurityTrustHtml(value);
    }
  }
}

เทมเพลต

{{ data.url | safe:'url' }}

แค่นั้นแหละ!

หมายเหตุ: คุณไม่จำเป็นต้องใช้ แต่นี่คือการใช้ส่วนประกอบของท่อ
  // Public properties
  itsSafe: SafeHtml;

  // Private properties
  private safePipe: SafePipe = new SafePipe(this.domSanitizer);

  /**
   * Component constructor
   *
   * @param safePipe: SafeHtml
   * @param domSanitizer: DomSanitizer
   */
  constructor(private safePipe: SafePipe, private domSanitizer: DomSanitizer) {
  }

  /**
   * On init
   */
  ngOnInit(): void {
    this.itsSafe = this.safePipe.transform('<h1>Hi</h1>', 'html');
  }

34

วิธีที่หรูหราที่สุดในการแก้ไขปัญหานี้:ใช้ท่อ นี่คือตัวอย่าง (บล็อกของฉัน) ดังนั้นคุณสามารถใช้url | safeไปป์เพื่อหลีกเลี่ยงการรักษาความปลอดภัย

<iframe [src]="url | safe"></iframe>

โปรดดูเอกสารใน npm สำหรับรายละเอียด: https://www.npmjs.com/package/safe-pipe


26

ใช้ Safe Pipe เพื่อแก้ไข

  • สร้างท่อที่ปลอดภัยหากคุณยังไม่มี

    ng gc ท่อปลอดภัย

  • เพิ่ม Safe pipe ใน app.module.ts

    การประกาศ: [SafePipe]

  • ประกาศท่อที่ปลอดภัยใน ts ของคุณ

นำเข้า Dom Sanitizer และ Safe Pipe เพื่อเข้าถึง url อย่างปลอดภัย

import { Pipe, PipeTransform} from '@angular/core';
import { DomSanitizer } from "@angular/platform-browser";

@Pipe({ name: 'safe' })

export class SafePipe implements PipeTransform {

constructor(private sanitizer: DomSanitizer) { }
transform(url) {
 return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

- เพิ่มความปลอดภัยด้วย src url

<iframe width="900" height="500" [src]="link | safe"/>

2
เยี่ยมมาก! สิ่งหนึ่งที่ไม่ควรเป็น 'ng g pipe safe' แทนที่จะเป็น 'ng gc pipe safe' อะไรที่เห็นได้ชัดว่าใช้ไม่ได้?
Jacob-Jan Mosselman

15

คุณสามารถให้เจลทำความสะอาดสัมผัสกับมุมมองหรือเปิดเผยวิธีการที่ส่งต่อการโทรไปยัง bypassSecurityTrustUrl

<img class='photo-img' [hidden]="!showPhoto1" 
    [src]='sanitizer.bypassSecurityTrustUrl(theMediaItem.photoURL1)'>

2

Angular ถือว่าค่าทั้งหมดไม่น่าเชื่อถือโดยค่าเริ่มต้น เมื่อใส่ค่าลงใน DOM จากเทมเพลตผ่านคุณสมบัติแอตทริบิวต์สไตล์การผูกคลาสหรือการแก้ไข Angular จะล้างข้อมูลและหลีกเลี่ยงค่าที่ไม่น่าเชื่อถือ

ดังนั้นหากคุณกำลังจัดการ DOM โดยตรงและแทรกเนื้อหาคุณจำเป็นต้องล้างมันให้สะอาดไม่เช่นนั้น Angular จะผ่านข้อผิดพลาด

ฉันได้สร้างท่อSanitizeUrlPipeสำหรับสิ่งนี้

import { PipeTransform, Pipe } from "@angular/core";
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";

@Pipe({
    name: "sanitizeUrl"
})
export class SanitizeUrlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustResourceUrl(v);
    }
}

และนี่คือวิธีที่คุณสามารถใช้ได้

<iframe [src]="url | sanitizeUrl" width="100%" height="500px"></iframe>

หากคุณต้องการเพิ่ม HTML SanitizeHtmlPipeสามารถช่วยได้

import { PipeTransform, Pipe } from "@angular/core";
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";

@Pipe({
    name: "sanitizeHtml"
})
export class SanitizeHtmlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustHtml(v);
    }
}

อ่านเพิ่มเติมเกี่ยวกับการรักษาความปลอดภัยเชิงมุมที่นี่


1

ฉันมักจะเพิ่มsafe pipeส่วนประกอบที่ใช้ซ้ำได้แยกต่างหากดังต่อไปนี้

# Add Safe Pipe

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({name: 'mySafe'})
export class SafePipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) {
    }

    public transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
}
# then create shared pipe module as following 

import { NgModule } from '@angular/core'; 
import { SafePipe } from './safe.pipe';
@NgModule({
    declarations: [
        SafePipe
    ],
    exports: [
        SafePipe
    ]
})
export class SharedPipesModule {
}
# import shared pipe module in your native module

@NgModule({
    declarations: [],
    imports: [
        SharedPipesModule,
    ],
})
export class SupportModule {
}
<!-------------------
call your url (`trustedUrl` for me) and add `mySafe` as defined in Safe Pipe
---------------->
<div class="container-fluid" *ngIf="trustedUrl">
    <iframe [src]="trustedUrl | mySafe" align="middle" width="100%" height="800" frameborder="0"></iframe>
</div>

0
import {DomSanitizationService} from '@angular/platform-browser';
@Component({
 templateUrl: 'build/pages/veeu/veeu.html'
 })
  export class VeeUPage {
     trustedURL:any;
      static get parameters() {
               return [NavController, App, MenuController, 
              DomSanitizationService];
        }
      constructor(nav, app, menu, sanitizer) {
        this.app = app;
        this.nav = nav;
        this.menu = menu;
        this.sanitizer = sanitizer;  
        this.trustedURL  = sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
        } 
 }



 <iframe [src]='trustedURL' width="640" height="360" frameborder="0"
   webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>


User property binding instead of function.

0

เป็นไปได้ที่จะตั้งค่าภาพเป็นภาพพื้นหลังเพื่อหลีกเลี่ยงunsafe urlข้อผิดพลาด:

<div [style.backgroundImage]="'url(' + imageUrl + ')'" class="show-image"></div>

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.