Como impedir que o IFRAME redirecione a janela de nível superior

133

Alguns sites têm código para "quebrar" os IFRAMEgabinetes, o que significa que, se uma página Afor carregada como uma IFRAMEpágina pai dentro de uma página pai, Palgum Javascript Aredirecionará a janela externa para A.

Normalmente, esse Javascript se parece com isso:

<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;
</script>

Minha pergunta é: como autor da página pai Pe não autor da página interna A, como posso evitar Aessa interrupção?

PS Parece-me que deveria ser uma violação de segurança entre sites, mas não é.

Jason Cohen
fonte
Eu não acho que você pode fazer muito ... se você não é o autor do conteúdo do quadro.
Scunliffe

Respostas:

43

Tente usar a propriedade onbeforeunload, que permitirá ao usuário escolher se deseja navegar para fora da página.

Exemplo: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

No HTML5, você pode usar a propriedade sandbox. Por favor, veja a resposta de Pankrat abaixo. http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

fasih.rana
fonte
1
iFrames fazer permitir a comunicação entre domínios, porém, utilizando postMessage. Isso não representa um risco à segurança, mas alguém pode querer saber que esse recurso existe quando vê seu comentário. :)
Coreyward
Não foi possível no momento em que escrevemos esta resposta. Obrigado por apontar.
fasih.rana
@SirDarius, por favor, mostre um exemplo muito apreciado.
usar o seguinte comando
O usuário não saberá por que essa confirmação aparece e provavelmente selecionará uma resposta aleatória. Eu não recomendo usá-lo. Existem outras soluções - o sandbox.
oriadam
1
@ fasih.rana O segundo artigo me ajudou muito. Obrigado ;)
MrD
127

Com HTML5, o atributo da caixa de areia iframe foi adicionado. No momento da redação, isso funciona no Chrome, Safari, Firefox e versões recentes do IE e Opera, mas faz praticamente o que você deseja:

<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

Se você deseja permitir redirecionamentos de nível superior, especifique sandbox="allow-top-navigation".

Pankrat
fonte
espere o que? Eles deixaram você fazer isso? Eu pensei que se um site quisesse sair, todos os navegadores deixariam. Como as pessoas devem manter seu site fora de iframes com isso? Mas não estou reclamando, demais.
Farzher
3
Aqui está o antídoto: blogs.msdn.com/b/ieinternals/archive/2010/03/30/…
Pankrat
1
@StephenSarcsamKamenar Se você deseja proteger seu site contra a exibição em iframe, existe o cabeçalho X-Frame-Options disponível com o valor SAMEORIGIN . Os navegadores mais modernos não exibirão o site em iframe com esse cabeçalho.
Grzegorz
4
Infelizmente sandbox, não permite o Flash ou qualquer outro tipo de objeto no quadro em área restrita, tornando o sandboxrecurso inútil em muitos casos.
oriadam 21/05
1
Os sites não devem "sair" para protestar contra a inclusão em um iframe. Eles podem simplesmente mostrar uma mensagem ou ficar em branco. Infelizmente, permitir que scripts sejam executados no iframe ainda o abre para um iframe não autorizado que executa while (1) {} e outros loops infinitos. Eu gostaria que cada iframe pudesse ter seu próprio encadeamento.
Gregory Magarshak 29/03
51

Eu uso sandbox = "..."

  • allow-forms permite o envio de formulários
  • allow-popups permite pop-ups
  • allow-pointer-lock permite o bloqueio do ponteiro
  • allow-same-origin permite que o documento mantenha sua origem
  • allow-scripts permite a execução de JavaScript e também permite que os recursos sejam acionados automaticamente
  • allow-top-navigation permite que o documento saia do quadro navegando na janela de nível superior

A navegação superior é o que você deseja impedir; portanto, deixe isso de fora e não será permitido. Qualquer coisa deixada de fora será bloqueada

ex.

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
adigioia
fonte
3
Observe que o Flash (e quaisquer outros objetos) também serão bloqueados, sem opção de permitir. Este "recurso de segurança" está a impedir-me de usar a caixa de areia todos juntos
oriadam
8

Depois de ler a especificação do w3.org . Encontrei a propriedade sandbox.

Você pode definir sandbox="", o que impede o redirecionamento do iframe. Dito isto, ele também não redirecionará o iframe. Você perderá o clique essencialmente.

Exemplo aqui: http://jsfiddle.net/ppkzS/1/
Exemplo sem sandbox: http://jsfiddle.net/ppkzS/

Parris
fonte
4

Eu sei que já faz muito tempo desde que a pergunta foi feita, mas aqui está a minha versão aprimorada que aguardará 500 ms por qualquer chamada subseqüente apenas quando o iframe for carregado.

<script type="text/javasript">
var prevent_bust = false ;
    var from_loading_204 = false;
    var frame_loading = false;
    var prevent_bust_timer = 0;
    var  primer = true;
    window.onbeforeunload = function(event) {
        prevent_bust = !from_loading_204 && frame_loading;
        if(from_loading_204)from_loading_204 = false;
        if(prevent_bust){
            prevent_bust_timer=500;
        }
    }
    function frameLoad(){
        if(!primer){
            from_loading_204 = true;
            window.top.location = '/?204';
            prevent_bust = false;
            frame_loading = true;
            prevent_bust_timer=1000;
        }else{
            primer = false;
        }
    }
    setInterval(function() {  
        if (prevent_bust_timer>0) {  
            if(prevent_bust){
                from_loading_204 = true;
                window.top.location = '/?204';
                prevent_bust = false;
            }else if(prevent_bust_timer == 1){
                frame_loading = false;
                prevent_bust = false;
                from_loading_204 = false;
                prevent_bust_timer == 0;
            }



        }
        prevent_bust_timer--;
        if(prevent_bust_timer==-100) {
            prevent_bust_timer = 0;
        }
    }, 1);
</script>

e onload="frameLoad()"e onreadystatechange="frameLoad();"tem de ser adicionado ao quadro ou iframe.

Luis Deleon
fonte
2

Como a página que você carrega dentro do iframe pode executar o código "breakout" com um setInterval, onbeforeunload pode não ser tão prático, pois pode deixar o usuário com 'Tem certeza de que deseja sair?' diálogos.

Há também o atributo de segurança iframe, que funciona apenas no IE & Opera

:(

user47087
fonte
2

No meu caso, quero que o usuário visite a página interna para que o servidor veja seu IP como visitante. Se eu usar a técnica de proxy php, acho que a página interna verá meu ip do servidor como visitante, portanto não é bom. A única solução que obtive até agora é a carga antes da carga. Coloque isso na sua página:

<script type="text/javascript">
    window.onbeforeunload = function () {                       
         return "This will end your session";
    }
</script>

Isso funciona tanto no firefox quanto no que eu testei. você encontrará versões usando algo como evt.return (tanto faz) porcaria ... que não funciona no firefox.

radu
fonte
0

Ao fazer isso, você poderá controlar qualquer ação da página emoldurada, que não poderá. A política de origem do mesmo domínio se aplica.

Diodeus - James MacFarlane
fonte
20
Não estou pedindo para controlar o que está dentro do IFRAME. Estou pedindo para impedir que o conteúdo do IFRAME me controle.
Jason Cohen