<img>: valor inseguro utilizado en un contexto de URL de recurso

109

Desde que actualicé al último candidato de lanzamiento de Angular 2, mis imgetiquetas:

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

están lanzando un error de navegador:

EXCEPCIÓN ORIGINAL: Error: valor no seguro utilizado en un contexto de URL de recurso

El valor de la URL es:

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

EDITAR:

Probé la sugerencia hecha en la otra solución de que se supone que esta pregunta es un duplicado, pero obtengo el mismo error.

He agregado el siguiente código al 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);
  }

Sigo recibiendo el mismo mensaje de error.

EDIT2:

También he cambiado el html a:

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

Sigo teniendo el mismo mensaje de error

Bill Noble
fuente
No tengo claro qué debo cambiar. ¿Cambio src = "{{something.else}}" a [src] = "something.else"?
Bill Noble
1
Exactamente:[src]='theMediaItem.photoURL1'
Günter Zöchbauer
Sí, lo intenté y aparece el mismo mensaje de error.
Bill Noble
¿Qué versión de Angular2 estás usando?
Günter Zöchbauer
Creo que estoy usando 2.0.0-beta.15 (estoy usando iónico y no estoy del todo seguro de cómo verificarlo) Disculpas por la forma en que agregué el código. No tengo claro el protocolo.
Bill Noble

Respuestas:

95

Estoy usando rc.4 y 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);
  }
}

En el HTML:

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

El uso de una función garantizará que el valor no cambie después de desinfectarlo. También tenga en cuenta que la función de desinfección que utiliza depende del contexto.

Para las imágenes, bypassSecurityTrustUrlfuncionará, pero para otros usos, debe consultar la documentación :

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

elkelk
fuente
3
¿Qué es "rc4" (y más tarde Helzgate se refiere a RC3 )? Quiero decir, ¿cómo lo asigno a una versión de github? Tanto en github como en npm solo veo versiones como 2.4.4 o 2.4.5. Actualmente estoy en 2.4.4 y parece que DomSanitizer cambió; así que esta es la importación que necesita:import {DomSanitizer} from '@angular/platform-browser';
The Red Pea
Oh, creo que las ramas github de angular se referirán a, 2.4.xpor ejemplo, pero las etiquetas github se referirán a candidatos de lanzamiento, como 2.0.0-rc3. Y puedo ver en rc3 , por ejemplo, la clase todavía se llamaba DomSanitizationService.
The Red Pea
1
this.sanitizer.bypassSecurityTrustResourceUrl(url)para videos
prayagupd
Lea la documentación detenidamente antes de usar esto: bypassSecurityTrustUrl () ADVERTENCIA: ¡ llamar a este método con datos de usuario que no son de confianza expone su aplicación a riesgos de seguridad XSS! Me parece que no es seguro hacerlo, a menos que esté realmente seguro de que se confía en la fuente de la imagen. Incluso si proviene de un servidor, si fue cargado por un usuario, sería posible explotar dicha solución.
March
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' }}

¡Eso es!

Nota: No debería necesitarlo, pero aquí está el uso de componentes de la tubería.
  // 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
fuente
24

Utilice Safe Pipe para arreglarlo.

  • Crea una tubería segura si no tienes ninguna.

    caja fuerte para tuberías ng gc

  • agregar tubería segura en app.module.ts

    declaraciones: [SafePipe]

  • declarar tubería segura en sus ts

Importe Dom Sanitizer y Safe Pipe para acceder a la URL de forma segura

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

- Agregar caja fuerte con src url

<iframe width="900" height="500" [src]="link | safe"/>
sjsj15
fuente
2
¡Excelente! Una cosa, ¿no debería ser 'ng g pipe safe' en lugar de 'ng gc pipe safe', lo que obviamente no funcionará?
Jacob-Jan Mosselman
15

O puede exponer el desinfectante a la vista o exponer un método que reenvía la llamada a bypassSecurityTrustUrl

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

Angular trata todos los valores como no confiables por defecto. Cuando se inserta un valor en el DOM desde una plantilla, a través de una propiedad, atributo, estilo, enlace de clase o interpolación, Angular desinfecta y escapa los valores que no son de confianza.

Entonces, si está manipulando DOM directamente e insertando contenido, debe desinfectarlo, de lo contrario Angular lo hará a través de errores.

He creado la tubería SanitizeUrlPipe para esto

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

y así es como puedes usar

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

Si desea agregar HTML, SanitizeHtmlPipe puede ayudar

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

Lea más sobre seguridad angular aquí .

Sunil Garg
fuente
1

Por lo general, agrego un safe pipecomponente reutilizable separado de la siguiente manera

# 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
fuente
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.
y yo
fuente
0

Es posible configurar la imagen como imagen de fondo para evitar unsafe urlerrores:

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

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
Aumentar
fuente