<img>: valeur non sécurisée utilisée dans un contexte d'URL de ressource

109

Depuis la mise à niveau vers la dernière version candidate d'Angular 2, mes imgbalises:

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

lancent une erreur de navigateur:

EXCEPTION ORIGINALE: Erreur: valeur non sécurisée utilisée dans un contexte d'URL de ressource

La valeur de l'url est:

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

ÉDITER:

J'ai essayé la suggestion faite dans l'autre solution selon laquelle cette question est censée être un double, mais j'obtiens la même erreur.

J'ai ajouté le code suivant au contrôleur:

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

Je reçois toujours le même message d'erreur.

EDIT2:

J'ai également changé le html en:

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

Je reçois toujours le même message d'erreur

Bill Noble
la source
Je ne sais pas exactement ce que je devrais changer. Est-ce que je change src = "{{something.else}}" en [src] = "something.else"?
Bill Noble
1
Exactement:[src]='theMediaItem.photoURL1'
Günter Zöchbauer
Oui, j'ai essayé et j'obtiens le même message d'erreur.
Bill Noble
Quelle version d'Angular2 utilisez-vous?
Günter Zöchbauer
Je pense que j'utilise 2.0.0-beta.15 (j'utilise ionic et je ne sais pas trop comment vérifier) ​​Toutes mes excuses pour la façon dont j'ai ajouté du code. Je ne suis pas clair sur le protocole.
Bill Noble

Réponses:

95

J'utilise rc.4 et cette méthode fonctionne pour 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);
  }
}

Dans le HTML:

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

L'utilisation d'une fonction garantit que la valeur ne change pas après l'avoir nettoyée. Sachez également que la fonction de nettoyage que vous utilisez dépend du contexte.

Pour les images, bypassSecurityTrustUrlcela fonctionnera mais pour d'autres utilisations, vous devez vous référer à la documentation :

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

Elkelk
la source
3
Qu'est-ce que "rc4" (et plus tard Helzgate fait référence à RC3 )? Je veux dire, comment mapper cela à une version github? Dans github et npm, je ne vois que des versions comme 2.4.4 ou 2.4.5. Je suis actuellement sur 2.4.4 et il semble que le DomSanitizer ait changé; voici donc l'importation dont vous avez besoin:import {DomSanitizer} from '@angular/platform-browser';
The Red Pea
Oh, je pense que les branches github d'angular se référeront 2.4.xpar exemple, mais les balises github feront référence à des versions candidates, comme 2.0.0-rc3. Et je peux voir dans rc3 , par exemple la classe était toujours nommée DomSanitizationService.
The Red Pea
1
this.sanitizer.bypassSecurityTrustResourceUrl(url)pour les vidéos
prieragupd
Lisez attentivement la documentation avant d'utiliser ceci: bypassSecurityTrustUrl () AVERTISSEMENT: l' appel de cette méthode avec des données utilisateur non fiables expose votre application à des risques de sécurité XSS! Il me semble que ce n'est pas sûr de le faire, à moins que vous ne soyez vraiment sûr de la source de confiance de l'image. Même s'il provient d'un serveur, s'il a été téléchargé par un utilisateur, il serait possible d'exploiter une telle solution.
Wilt
144

Tuyau

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

Modèle

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

C'est tout!

Remarque: vous ne devriez pas en avoir besoin mais voici l'utilisation du composant du tuyau
  // 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
la source
24

Utilisez Safe Pipe pour le réparer.

  • Créez un tuyau sûr si vous n'en avez pas.

    ng gc pipe safe

  • ajouter Safe pipe dans app.module.ts

    déclarations: [SafePipe]

  • déclarer un tuyau sûr dans votre ts

Importez Dom Sanitizer et Safe Pipe pour accéder à l'URL en toute sécurité

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

- Ajouter un coffre-fort avec l'url src

<iframe width="900" height="500" [src]="link | safe"/>
sjsj15
la source
2
Génial! Une chose, ne devrait-il pas être «ng g pipe safe» au lieu de «ng gc pipe safe», qu'est-ce qui ne fonctionnera évidemment pas?
Jacob-Jan Mosselman le
15

Soit vous pouvez exposer sanitizer à la vue, soit exposer une méthode qui transfère l'appel à bypassSecurityTrustUrl

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

Angular traite toutes les valeurs comme non approuvées par défaut. Lorsqu'une valeur est insérée dans le DOM à partir d'un modèle, via une propriété, un attribut, un style, une liaison de classe ou une interpolation, Angular nettoie et échappe les valeurs non approuvées.

Donc, si vous manipulez directement DOM et insérez du contenu, vous devez le nettoyer, sinon Angular le fera par des erreurs.

J'ai créé le tuyau SanitizeUrlPipe pour cela

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

et voici comment vous pouvez utiliser

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

Si vous souhaitez ajouter du HTML, SanitizeHtmlPipe peut vous aider

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

En savoir plus sur la sécurité angulaire ici .

Sunil Garg
la source
1

J'ajoute généralement un safe pipecomposant réutilisable séparé comme suit

# 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
la source
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
la source
0

Il est possible de définir l'image comme image d'arrière-plan pour éviter les unsafe urlerreurs:

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

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
StepUp
la source