<img>: valor não seguro usado em um contexto de URL de recurso

109

Desde a atualização para o último candidato a lançamento do Angular 2, minhas imgtags:

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

estão gerando um erro do navegador:

EXCEÇÃO ORIGINAL: Erro: valor inseguro usado em um contexto de URL de recurso

O valor do url é:

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

EDITAR:

Tentei a sugestão feita na outra solução de que essa pergunta deveria ser uma duplicata, mas estou recebendo o mesmo erro.

Eu adicionei o seguinte código ao controlador:

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

Ainda estou recebendo a mesma mensagem de erro.

EDIT2:

Eu também mudei o html para:

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

Eu ainda recebo a mesma mensagem de erro

Bill Noble
fonte
Não estou certo sobre o que devo mudar. Devo mudar src = "{{algo.else}}" para [src] = "algo.else"?
Bill Noble de
1
Exatamente:[src]='theMediaItem.photoURL1'
Günter Zöchbauer
Sim, eu tentei isso e recebo a mesma mensagem de erro.
Bill Noble de
Qual versão do Angular2 você está usando?
Günter Zöchbauer de
Acho que estou usando 2.0.0-beta.15 (estou usando iônico e não tenho certeza de como verificar) Desculpas pela forma como adicionei o código, não tenho certeza sobre o protocolo.
Bill Noble de

Respostas:

95

Estou usando rc.4 e este método funciona para 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);
  }
}

No HTML:

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

O uso de uma função garantirá que o valor não mude depois de limpá-lo. Também esteja ciente de que a função de sanitização que você usa depende do contexto.

Para imagens, bypassSecurityTrustUrlfuncionará, mas para outros usos, você precisa consultar a documentação :

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

Elkelk
fonte
3
O que é "rc4" (e posteriormente Helzgate se refere a RC3 )? Quer dizer, como mapeio isso para uma versão do github? Tanto no github quanto no npm, só vejo versões como 2.4.4 ou 2.4.5. Atualmente estou no 2.4.4 e parece que o DomSanitizer mudou; então esta é a importação de que você precisa:import {DomSanitizer} from '@angular/platform-browser';
The Red Pea
Oh, eu acho que os branches github do angular irão se referir a, 2.4.xpor exemplo, mas as tags github irão se referir a candidatos a lançamento, como 2.0.0-rc3. E posso ver no rc3 , por exemplo, a classe ainda tinha um nome DomSanitizationService.
The Red Pea
1
this.sanitizer.bypassSecurityTrustResourceUrl(url)para vídeos
prayagupd
Leia a documentação cuidadosamente antes de usar isso: bypassSecurityTrustUrl () AVISO: chamar esse método com dados de usuário não confiáveis ​​expõe seu aplicativo a riscos de segurança XSS! Parece-me que não é seguro fazer isso, a menos que você tenha certeza de que a fonte da imagem é confiável. Mesmo que venha de um servidor, se for carregado por um usuário, seria possível explorar tal solução.
Wilt
144

Tubo

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

Modelo

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

É isso aí!

Nota: Você não deveria precisar, mas aqui está o uso de componente do tubo
  // 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
fonte
24

Use Safe Pipe para consertá-lo.

  • Crie um tubo seguro se você não tiver nenhum.

    ng gc pipe safe

  • adicione o canal seguro em app.module.ts

    declarações: [SafePipe]

  • declare um tubo seguro em seu ts

Importe Dom Sanitizer e Safe Pipe para acessar a url com segurança

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

- Adicionar seguro com url src

<iframe width="900" height="500" [src]="link | safe"/>
sjsj15
fonte
2
Ótimo! Uma coisa, não deveria ser 'ng g pipe safe' em vez de 'ng gc pipe safe', o que obviamente não funcionaria?
Jacob-Jan Mosselman
15

Você pode expor o sanitizer para a visualização ou expor um método que encaminha a chamada para bypassSecurityTrustUrl

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

Angular trata todos os valores como não confiáveis ​​por padrão. Quando um valor é inserido no DOM a partir de um modelo, por meio de propriedade, atributo, estilo, associação de classe ou interpolação, o Angular limpa e escapa de valores não confiáveis.

Portanto, se você está manipulando o DOM diretamente e inserindo conteúdo nele, é necessário higienizá-lo, caso contrário o Angular o fará por meio de erros.

Eu criei o pipe SanitizeUrlPipe para este

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

e é assim que você pode usar

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

Se você deseja adicionar HTML, SanitizeHtmlPipe pode ajudar

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

Leia mais sobre segurança angular aqui .

Sunil Garg
fonte
1

Eu geralmente adiciono safe pipecomponentes reutilizáveis separados como segue

# 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
fonte
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
fonte
0

É possível definir a imagem como imagem de fundo para evitar unsafe urlerros:

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

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
Um passo adiante
fonte