<img>: Небезпечне значення, яке використовується в контексті URL-адреси ресурсу


109

З моменту оновлення до останнього кандидата випуску 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);
  }

Я все ще отримую те саме повідомлення про помилку.

EDIT2:

Я також змінив HTML на:

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

Я все одно отримую те саме повідомлення про помилку


Мені не ясно, що я повинен змінити. Чи потрібно змінити src = "{{something.else}}" на [src] = "something.else"?
Білл Благородний

1
Рівно:[src]='theMediaItem.photoURL1'
Günter Zöchbauer

Так, я спробував це, і я отримав те саме повідомлення про помилку.
Білл Благородний

Яку версію Angular2 ви використовуєте?
Günter Zöchbauer

Я думаю, що я використовую 2.0.0-beta.15 (я використовую іонний і зовсім не впевнений, як перевірити) Вибачення за те, що я додав код, мені не зрозуміло в протоколі.
Білл Благородний

Відповіді:


95

Я використовую 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';
Червоний горох

О, я думаю , гілки кутових github будуть посилатися на 2.4.xприклад, але теги github посилаються на звільнення кандидатів, наприклад 2.0.0-rc3. І я можу побачити в rc3 , наприклад, клас ще був названий DomSanitizationService.
Червоний горох

1
this.sanitizer.bypassSecurityTrustResourceUrl(url)для відео
prayagupd

Перед використанням уважно прочитайте документацію: bypassSecurityTrustUrl () ПОПЕРЕДЖЕННЯ: виклик цього методу з ненадійними даними користувача піддає вашій програмі ризики безпеки XSS! Мені здається, що це робити не безпечно, якщо ви справді не впевнені в тому, що джерелу зображення довіряють. Навіть якщо він надходить із сервера, якщо його завантажив користувач, можна було б скористатися таким рішенням.
Уїлт

144

Труба

// 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');
  }

33

Найелегантніший спосіб виправити це: використовувати трубу. Ось приклад (мій блог). Тоді ви можете просто використовувати url | safeтрубу для обходу безпеки.

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

Для отримання детальної інформації зверніться до документації на npm: https://www.npmjs.com/package/safe-pipe


24

Використовуйте безпечну трубу, щоб виправити її.

  • Створіть безпечну трубу, якщо у вас її немає.

    ng gc труби безпечно

  • додати безпечну трубу в app.module.ts

    декларації: [SafePipe]

  • оголосити безпечну трубу у вашому ц

Імпортуйте 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);
  }
}

- Додати безпечний URL-адресу src

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

2
Чудово! Одне, чи не повинен це бути "ng g pipe safe" замість "ng gc pipe safe", що очевидно не буде працювати?
Яків-Ян Моссельман

15

Або ви можете піддавати дезінсимулятор виду, або викрити метод, який пересилає виклик в bypassSecurityTrustUrl

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

2

Angular розглядає всі значення як недовірені за замовчуванням. Коли значення вставляється в DOM із шаблону через властивість, атрибут, стиль, прив'язку класу чи інтерполяцію, Angular sanitizes та уникає недовірених значень.

Отже, якщо ви маніпулюєте DOM безпосередньо та вставляєте вміст у нього, вам потрібно санітувати його, інакше кутова воля через помилки.

Я створив труби 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;        
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.