<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


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


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


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

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

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 .


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>

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

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;        
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.