Cómo evitar que IFRAME redirija la ventana de nivel superior

133

Algunos sitios web tienen un código para "salir" de los IFRAMErecintos, lo que significa que si una página Ase carga como IFRAMEdentro de una página principal, Palgunos JavaScript Aredirigen la ventana exterior A.

Por lo general, este Javascript se parece a esto:

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

Mi pregunta es: como autor de la página principal Py no siendo el autor de la página interna A, ¿cómo puedo evitar Ahacer este desglose?

PD: Me parece que debería ser una violación de seguridad entre sitios, pero no lo es.

Jason Cohen
fuente
No creo que puedas hacer mucho ... si no eres el autor del contenido del marco.
scunliffe

Respuestas:

43

Intente usar la propiedad onbeforeunload, que le permitirá al usuario elegir si desea navegar fuera de la página.

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

En HTML5 puedes usar la propiedad sandbox. Por favor, consulte la respuesta de Pankrat a continuación. http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

fasih.rana
fuente
1
Sin embargo , iFrames permite la comunicación entre dominios mediante el uso postMessage. Esto no es un riesgo de seguridad, pero a alguien le puede interesar saber que esta capacidad existe cuando ve su comentario. :)
coreyward
No fue posible al momento de escribir esta respuesta. Gracias por señalarlo.
fasih.rana
@SirDarius, ¿podría mostrar un ejemplo, muy apreciado?
user198989
El usuario no sabrá por qué aparece esta confirmación y probablemente seleccionará una respuesta aleatoria. No recomiendo usarlo. Hay otras soluciones: la sandbox.
oriadam
1
@ fasih.rana El segundo artículo me ayudó mucho. Gracias;)
MrD
127

Con HTML5 se agregó el atributo de caja de arena de iframe . Al momento de escribir esto, funciona en Chrome, Safari, Firefox y versiones recientes de IE y Opera, pero hace más o menos lo que quieres:

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

Si desea permitir redirecciones de nivel superior, especifique sandbox="allow-top-navigation".

Pankrat
fuente
¿esperar lo? ¿Te dejan hacer esto? Pensé que si un sitio web quería salir, todos los navegadores lo dejarían. ¿Cómo se supone que las personas deben mantener su sitio web fuera de iframes con esto? Sin embargo, no me estoy quejando, increíble.
Farzher
3
Aquí está el antídoto: blogs.msdn.com/b/ieinternals/archive/2010/03/30/…
Pankrat
1
@StephenSarcsamKamenar Si desea proteger su sitio para que no se muestre en iframe, hay un encabezado X-Frame-Options disponible con el valor SAMEORIGIN . La mayoría de los navegadores modernos no mostrarán el sitio en iframe con este encabezado.
Grzegorz
44
Lamentablemente sandbox, no permite Flash ni ningún otro tipo de objeto en el marco de espacio aislado, lo que hace que la sandboxfunción sea inútil en muchos casos.
oriadam
1
Los sitios web no deben "explotar" para protestar por la inclusión en un iframe. Simplemente pueden mostrar un mensaje o quedar en blanco. Desafortunadamente, permitir que los scripts se ejecuten en el iframe todavía te abre a un iframe falso mientras hace (1) {} y otros bucles infinitos. Desearía que cada iframe pudiera tener su propio hilo.
Gregory Magarshak
51

Yo uso sandbox = "..."

  • permitir formularios permite el envío de formularios
  • allow-popups permite popups
  • permitir bloqueo de puntero permite bloqueo de puntero
  • allow-same-origin permite que el documento mantenga su origen
  • allow-scripts permite la ejecución de JavaScript y también permite que las características se activen automáticamente
  • allow-top-navigation permite que el documento salga del marco navegando por la ventana de nivel superior

La navegación superior es lo que desea evitar, así que no lo permita y no se permitirá. Todo lo que quede fuera será bloqueado

ex.

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
adigioia
fuente
3
Tenga en cuenta que Flash (y cualquier otro objeto) también se bloqueará, sin opción de permitirlo. Esta "característica de seguridad" me impide usar sandbox todos juntos
oriadam
4

Sé que ha pasado mucho tiempo desde que se hizo la pregunta, pero aquí está mi versión mejorada, esperará 500 ms para cualquier llamada posterior solo cuando se cargue el iframe.

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

y onload="frameLoad()"y onreadystatechange="frameLoad();"deben agregarse al marco o al iframe.

Luis Deleon
fuente
2

Dado que la página que carga dentro del iframe puede ejecutar el código de "ruptura" con un setInterval, onbeforeunload podría no ser tan práctico, ya que podría confundir al usuario con '¿Está seguro de que quiere irse?' diálogos

También existe el atributo de seguridad iframe que solo funciona en IE y Opera

:(

user47087
fuente
2

En mi caso, quiero que el usuario visite la página interna para que el servidor vea su IP como visitante. Si uso la técnica de proxy php, creo que la página interna verá la dirección IP de mi servidor como visitante, por lo que no es bueno. La única solución que obtuve hasta ahora es antes de la descarga. Pon esto en tu página:

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

Esto funciona tanto en Firefox como en eso es lo que probé. encontrarás versiones que usan algo como evt.return (lo que sea) basura ... que no funciona en firefox.

radu
fuente
0

Al hacerlo, podrá controlar cualquier acción de la página enmarcada, que no puede. Se aplica la política de origen del mismo dominio .

Diodeus - James MacFarlane
fuente
20
No estoy pidiendo controlar lo que hay dentro del IFRAME. Estoy pidiendo evitar que lo que está dentro del IFRAME me controle.
Jason Cohen