Como definir <iframe src = "…"> sem causar a exceção de `valor inseguro`?

164

Estou trabalhando em um tutorial envolvendo a configuração de um iframe srcatributo:

<iframe width="100%" height="300" src="{{video.url}}"></iframe>

Isso gera uma exceção:

Error: unsafe value used in a resource URL context
at DomSanitizationServiceImpl.sanitize...

Eu já tentei usar ligações [src]sem sucesso.

TJ.
fonte

Respostas:

343

Atualização v8

As respostas abaixo funcionam, mas expõem seu aplicativo a riscos de segurança XSS! . Em vez de usar this.sanitizer.bypassSecurityTrustResourceUrl(url), é recomendável usarthis.sanitizer.sanitize(SecurityContext.URL, url)

Atualizar

Para a versão RC.6 ^ , use o DomSanitizer

Plunker

E uma boa opção é usar tubo puro para isso:

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

lembre-se de adicionar seu novo SafePipeà declarationsmatriz do AppModule. ( como visto na documentação )

@NgModule({
   declarations : [
     ...
     SafePipe
   ],
})

html

<iframe width="100%" height="300" [src]="url | safe"></iframe>

Plunker

Se você usar a embedtag, isso pode ser interessante para você:


Versão antiga RC.5

Você pode aproveitar DomSanitizationServiceassim:

export class YourComponent {
  url: SafeResourceUrl;
  constructor(sanitizer: DomSanitizationService) {
    this.url = sanitizer.bypassSecurityTrustResourceUrl('your url');
  }
}

E, em seguida, vincule-o ao urlseu modelo:

<iframe width="100%" height="300" [src]="url"></iframe>

Não se esqueça de adicionar as seguintes importações:

import { SafeResourceUrl, DomSanitizationService } from '@angular/platform-browser';

Amostra Plunker

yurzui
fonte
1
@FugueWeb Isso ocorre porque o ionic2 está usando o RC4 angular hoje. github.com/driftyco/ionic/blob/master/…
yurzui
2
Estou usando o Ionic2. Declaro um pipe Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url): any { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } e no modelo eu chamo <iframe width="100%" height="315" src="{{url}} | safe" frameborder="0" allowfullscreen></iframe>. Mas não funciona com o erro 'valor inseguro'. Por favor ajude
Insane Rose
1
@Insane Rose eu acho que deveria ser [src]="url | safe"apenas suportes remova
yurzui
7
@yurzui Segui sua recomendação para a v8 atualizada. No entanto, quando eu uso this.sanitizer.sanitize(SecurityContext.URL, url), estou recebendo o erro "Erro de erro: valor inseguro usado em um contexto de URL de recurso" II altere-o para que this.sanitizer.bypassSecurityTrustResourceUrl(url)funcione bem. Alguma idéia do que pode estar errado?
Kosmonaft 22/07/19
2
this.sanitizer.sanitize(SecurityContext.URL, url)não funciona e this.sanitizer.bypassSecurityTrustResourceUrl(url)funciona, mas levanta um problema de vulnerabilidade de alta segurança na análise de código estático, o que me impede de mudar isso para produção. Preciso de uma maneira de consertar isso
cjkumaresh
28

Este funciona para mim.

import { Component,Input,OnInit} from '@angular/core';
import {DomSanitizer,SafeResourceUrl,} from '@angular/platform-browser';

@Component({
    moduleId: module.id,
    selector: 'player',
    templateUrl: './player.component.html',
    styleUrls:['./player.component.scss'],
    
})
export class PlayerComponent implements OnInit{
    @Input()
    id:string; 
    url: SafeResourceUrl;
    constructor (public sanitizer:DomSanitizer) {
    }
    ngOnInit() {
        this.url = this.sanitizer.bypassSecurityTrustResourceUrl(this.id);      
    }
}
vikvincer
fonte
Essa abordagem funciona para mim, pois eu uso isso em um só lugar. Caso contrário, a abordagem de tubulação é melhor.
Narek Tootikian
@Pang Como funciona? Eu tenho o mesmo problema que eu quero adicionar meu parâmetro em url. Estou usando esses códigos "@Input () parameterForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" mas não está funcionando problema no parâmetro.
Arjun Walmiki
15

Isso funciona para o Angular 5.2.0

sarasa.Component.ts

import { Component, OnInit, Input } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';

@Component({
  selector: 'app-sarasa',
  templateUrl: './sarasa.component.html',
  styleUrls: ['./sarasa.component.scss']
})

export class Sarasa implements OnInit {
  @Input()
  url: string = "https://www.mmlpqtpkasjdashdjahd.com";
  urlSafe: SafeResourceUrl;

  constructor(public sanitizer: DomSanitizer) { }

  ngOnInit() {
    this.urlSafe= this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
  }

}

sarasa.Component.html

<iframe width="100%" height="100%" frameBorder="0" [src]="urlSafe"></iframe>

isso é tudo, pessoal!!!

Lrodriguez84
fonte
7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

Eu estava lutando por 4 horas. o problema estava na tag img. Quando você usa colchete para 'src' ex: [src]. você não pode usar esta expressão angular {{}}. você apenas fornece diretamente de um exemplo de objeto abaixo. se você der expressão angular {{}}. você receberá um erro de interpolação.

  1. primeiro eu usei ngFor para iterar os países

    *ngFor="let country of countries"
    
  2. segundo, você coloca isso na tag img. é isso.

    <img [src]="sanitizer.bypassSecurityTrustResourceUrl(country.flag)"
    height="20" width="20" alt=""/>
    
Kumaresan Perumal
fonte
Esteja ciente de que colocar uma chamada de função dentro do HTML é uma má ideia, pois será chamada toda vez que o ChangeDetector verificará alterações.
karolus
1

Também deparei com esse problema, mas para usar um pipe seguro no meu módulo angular, instalei o pacote npm do safe-pipe, que você pode encontrar aqui . Para sua informação, isso funcionou no Angular 9.1.3, não tentei isso em nenhuma outra versão do Angular. Veja como você o adiciona passo a passo:

  1. Instale o pacote via npm install pipe-safe ou wire add-safe-pipe. Isso armazenará uma referência a ele em suas dependências no arquivo package.json, que você já deveria ter ao iniciar um novo projeto Angular.

  2. Adicione o módulo SafePipeModule ao NgModule.imports no arquivo do módulo Angular da seguinte maneira:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. Adicione o pipe seguro a um elemento no modelo do componente Angular que você está importando para o seu NgModule da seguinte maneira:

<element [property]="value | safe: sanitizationType"></element>
  1. Aqui estão alguns exemplos específicos do safePipe em um elemento html:
<div [style.background-image]="'url(' + pictureUrl + ')' | safe: 'style'" class="pic bg-pic"></div>
<img [src]="pictureUrl | safe: 'url'" class="pic" alt="Logo">
<iframe [src]="catVideoEmbed | safe: 'resourceUrl'" width="640" height="390"></iframe>
<pre [innerHTML]="htmlContent | safe: 'html'"></pre>

LRitter
fonte
-1

Eu costumo adicionar componente reutilizável de tubo seguro separado da seguinte maneira

# 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
-8

Parabéns! ¨ ^^ Eu tenho uma solução fácil e eficiente para você, sim!

<iframe width="100%" height="300" [attr.src]="video.url"></iframe

[attr.src] em vez de src "video.url" e não {{video.url}}

Ótimo ;)

Smaillns
fonte
5
Isso não faz diferença para os valores das strings.
Günter Zöchbauer
1
isso não funciona. Recebendo mensagem de errounsafe value used in a resource URL context
Derek Liang
Portanto, você pode usar a tag de vídeo html5, mas se insistir em usar o iframe (por vários motivos;), consulte outras soluções que usam o DomSanitizationService.
Smaillns
então, se você está procurando usar a tag 'video', será assim <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> , também poderá usá-lo para exibir documentos também .. se você tiver algum problema ao usar a tag de vídeo, eu estou aqui;)
Smaillns