<img>: niebezpieczna wartość używana w kontekście adresu URL zasobu

109

Od czasu aktualizacji do najnowszego kandydata do wydania Angular 2 moje imgtagi:

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

zgłaszają błąd przeglądarki:

ORYGINALNY WYJĄTEK: Błąd: niebezpieczna wartość używana w kontekście adresu URL zasobu

Wartość adresu URL to:

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

EDYTOWAĆ:

Wypróbowałem sugestię z innego rozwiązania, że ​​to pytanie ma być duplikatem, ale otrzymuję ten sam błąd.

Dodałem do sterownika następujący kod:

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

Nadal otrzymuję ten sam komunikat o błędzie.

EDYCJA2:

Zmieniłem też HTML na:

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

Nadal otrzymuję ten sam komunikat o błędzie

Bill Noble
źródło
Nie wiem, co powinienem zmienić. Czy mogę zmienić src = "{{something.else}}" na [src] = "something.else"?
Bill Noble
1
Dokładnie:[src]='theMediaItem.photoURL1'
Günter Zöchbauer
Tak, próbowałem i otrzymuję ten sam komunikat o błędzie.
Bill Noble
Jakiej wersji Angular2 używasz?
Günter Zöchbauer
Myślę, że używam wersji 2.0.0-beta.15 (używam jonowego i nie do końca wiem, jak to sprawdzić) Przepraszamy za sposób dodania kodu. Nie mam jasności co do protokołu.
Bill Noble

Odpowiedzi:

95

Używam rc.4 i ta metoda działa dla 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);
  }
}

W HTML:

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

Użycie funkcji zapewni, że wartość nie zmieni się po jej oczyszczeniu. Należy również pamiętać, że używana funkcja sanityzacji zależy od kontekstu.

W przypadku obrazów bypassSecurityTrustUrlbędzie działać, ale w przypadku innych zastosowań należy zapoznać się z dokumentacją :

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

elkelk
źródło
3
Co to jest „rc4” (a później Helzgate odnosi się do RC3 )? Mam na myśli, jak mam to zmapować do wersji na githubie? Zarówno w github, jak i npm widzę tylko wersje takie jak 2.4.4 lub 2.4.5. Jestem obecnie na 2.4.4 i wygląda na to, że DomSanitizer się zmienił; więc to jest import, którego potrzebujesz:import {DomSanitizer} from '@angular/platform-browser';
Czerwony groszek
Och, myślę, że gałęzie github angulara będą odnosić się na przykład, ale tagi github będą odnosić się do kandydatów do wydania, takich jak . I widzę w rc3 , na przykład klasa była nadal nazwana . 2.4.x2.0.0-rc3DomSanitizationService
The Red Pea
1
this.sanitizer.bypassSecurityTrustResourceUrl(url)dla filmów
prayagupd
Przeczytaj uważnie dokumentację, zanim skorzystasz z tego: bypassSecurityTrustUrl () OSTRZEŻENIE: wywołanie tej metody z niezaufanymi danymi użytkownika naraża Twoją aplikację na zagrożenia bezpieczeństwa XSS! Wydaje mi się, że nie jest to bezpieczne, chyba że jesteś naprawdę pewien, że źródło obrazu jest zaufane. Nawet jeśli pochodzi z serwera, gdyby został załadowany przez użytkownika, można by było wykorzystać takie rozwiązanie.
Wilt
144

Rura

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

Szablon

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

Otóż ​​to!

Uwaga: Nie powinieneś tego potrzebować, ale tutaj jest użycie komponentu rury
  // 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');
  }
Helzgate
źródło
24

Użyj Safe Pipe, aby to naprawić.

  • Utwórz bezpieczną rurę, jeśli jej nie masz.

    ng gc pipe bezpieczne

  • dodaj Safe Pipe w app.module.ts

    deklaracje: [SafePipe]

  • zadeklaruj bezpieczną rurę w swoim ts

Importuj Dom Sanitizer i Safe Pipe, aby bezpiecznie uzyskać dostęp do adresu 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);
  }
}

- Dodaj sejf z adresem URL src

<iframe width="900" height="500" [src]="link | safe"/>
sjsj15
źródło
2
Wspaniały! Po pierwsze, czy nie powinno być „ng g pipe safe” zamiast „ng gc pipe safe”, co oczywiście nie zadziała?
Jacob-Jan Mosselman
15

Albo możesz udostępnić sanitizer do widoku, albo ujawnić metodę, która przekazuje wywołanie do bypassSecurityTrustUrl

<img class='photo-img' [hidden]="!showPhoto1" 
    [src]='sanitizer.bypassSecurityTrustUrl(theMediaItem.photoURL1)'>
Nguyễn Việt Trung
źródło
2

Angular domyślnie traktuje wszystkie wartości jako niezaufane. Kiedy wartość jest wstawiana do DOM z szablonu, poprzez właściwość, atrybut, styl, wiązanie klasy lub interpolację, Angular oczyszcza i usuwa niezaufane wartości.

Więc jeśli bezpośrednio manipulujesz DOM i wstawiasz do niego zawartość, musisz go oczyścić, w przeciwnym razie Angular popełni błędy.

Stworzyłem rurę SanitizeUrlPipe tego

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

i tak możesz używać

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

Jeśli chcesz dodać HTML, może pomóc 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);
    }
}

Przeczytaj więcej o zabezpieczeniach kątowych tutaj .

Sunil Garg
źródło
1

Zwykle dodaję oddzielny safe pipekomponent wielokrotnego użytku w następujący sposób

# 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>
Janki
źródło
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.
ani
źródło
0

Możliwe jest ustawienie obrazu jako obrazu tła, aby uniknąć unsafe urlbłędu:

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

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
StepUp
źródło