SecurityError: Se bloqueó el acceso de un marco con origen a un marco de origen cruzado

Resuelto mubashermubi asked hace 10 años • 9 respuestas

Estoy cargando un <iframe>en mi página HTML e intentando acceder a los elementos que contiene usando JavaScript, pero cuando intento ejecutar mi código, aparece el siguiente error:

SecurityError: se bloqueó el acceso de un marco con origen "http://www.example.com" a un marco de origen cruzado.

¿Cómo puedo acceder a los elementos del marco?

Estoy usando este código para realizar pruebas, pero es en vano:

$(document).ready(function() {
    var iframeWindow = document.getElementById("my-iframe-id").contentWindow;

    iframeWindow.addEventListener("load", function() {
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        var target = doc.getElementById("my-target-id");

        target.innerHTML = "Found it!";
    });
});
mubashermubi avatar Aug 03 '14 01:08 mubashermubi
Aceptado

Política del mismo origen

No puedes acceder a un <iframe>origen diferente usando JavaScript; sería una gran falla de seguridad si pudieras hacerlo. Para la política del mismo origen, los navegadores bloquean los scripts que intentan acceder a un marco con un origen diferente .

El origen se considera diferente si no se mantiene al menos una de las siguientes partes de la dirección:

protocolo :// nombre de host : puerto /...

El protocolo, el nombre de host y el puerto deben ser los mismos que los de su dominio si desea acceder a una trama.

NOTA: aunque hoy en día casi no se utiliza, se sabe que Internet Explorer no sigue estrictamente esta regla; consulte aquí para obtener más detalles.

Ejemplos

Esto es lo que sucedería al intentar acceder a las siguientes URL desdehttp://www.example.com/home/index.html

URL                                             RESULT
http://www.example.com/home/other.html       -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80                    -> Success (default port for HTTP)
http://www.example.com:2251                  -> Failure: different port
http://data.example.com/dir/other.html       -> Failure: different hostname
https://www.example.com/home/index.html:80   -> Failure: different protocol
ftp://www.example.com:21                     -> Failure: different protocol & port
https://google.com/search?q=james+bond       -> Failure: different protocol, port & hostname

Solución alterna

Aunque la política del mismo origen impide que los scripts accedan al contenido de sitios con un origen diferente, si posee ambas páginas, puede solucionar este problema usando window.postMessagey su messageevento relativo para enviar mensajes entre las dos páginas, como este:

  • En tu página principal:

    const frame = document.getElementById('your-frame-id');
    frame.contentWindow.postMessage(/*any variable or object here*/, 'https://your-second-site.example');
    

    El segundo argumento para postMessage()poder ser '*'no indicar preferencia sobre el origen del destino. Siempre que sea posible, siempre se debe proporcionar un origen de destino, para evitar revelar los datos que envía a cualquier otro sitio.

  • En su <iframe>(contenido en la página principal):

    window.addEventListener('message', event => {
        // IMPORTANT: check the origin of the data!
        if (event.origin === 'https://your-first-site.example') {
            // The data was sent from your site.
            // Data sent with postMessage is stored in event.data:
            console.log(event.data);
        } else {
            // The data was NOT sent from your site!
            // Be careful! Do not use it. This else branch is
            // here just for clarity, you usually shouldn't need it.
            return;
        }
    });
    

Este método se puede aplicar en ambas direcciones , creando también un oyente en la página principal y recibiendo respuestas del marco. La misma lógica también se puede implementar en ventanas emergentes y básicamente en cualquier ventana nueva generada por la página principal (por ejemplo, usando window.open()), sin ninguna diferencia.

Deshabilitar la política del mismo origen en su navegador

Ya hay algunas buenas respuestas sobre este tema (las encontré buscando en Google), por lo que, para los navegadores donde esto sea posible, vincularé la respuesta relativa. Sin embargo, recuerde que deshabilitar la política del mismo origen solo afectará a su navegador . Además, ejecutar un navegador con la configuración de seguridad del mismo origen deshabilitada otorga a cualquier sitio web acceso a recursos de orígenes cruzados, por lo que es muy inseguro y NUNCA debe hacerse si no sabe exactamente lo que está haciendo (por ejemplo, con fines de desarrollo) .

  • Google Chrome
  • Mozilla Firefox
  • Safari
  • Opera : igual que Chrome
  • Microsoft Edge: igual que Chrome
  • Valiente: igual que Chrome
  • Microsoft Edge (versión antigua que no es Chromium): no es posible
  • Microsoft Internet Explorer
Marco Bonelli avatar Aug 02 '2014 18:08 Marco Bonelli

Complementando la respuesta de Marco Bonelli: la mejor forma actual de interactuar entre marcos/iframes es utilizar window.postMessage, compatible con todos los navegadores

Geert avatar Oct 09 '2014 14:10 Geert

Verifique la http://www.example.comconfiguración del servidor web del dominio X-Frame-Options . Es una característica de seguridad diseñada para evitar ataques de clickJacking.

¿Cómo funciona el clickJacking?

  1. La página malvada se ve exactamente igual a la página de la víctima.
  2. Luego engañó a los usuarios para que ingresaran su nombre de usuario y contraseña.

Técnicamente, el mal tiene una iframefuente con la página de la víctima.

<html>
    <iframe src='victim-domain.example'/>
    <input id="username" type="text" style="display: none;"/>
    <input id="password" type="text" style="display: none;"/>
    <script>
        //some JS code that click jacking the user username and input from inside the iframe...
    <script/>
<html>

Cómo funciona la característica de seguridad

Si desea evitar que la solicitud del servidor web se procese dentro de un iframecomplemento, agregue las opciones de marco x

Opciones de X-Frame DENEGAR

Las opciones son:

  1. SAMEORIGIN: permitir que solo mi propio dominio represente mi HTML dentro de un iframe.
  2. DENY: no permitir que mi HTML se represente dentro de ningún iframe
  3. ALLOW-FROM https://example.com/: permitir que un dominio específico represente mi HTML dentro de un iframe

Este es un ejemplo de configuración de IIS:

   <httpProtocol>
       <customHeaders>
           <add name="X-Frame-Options" value="SAMEORIGIN" />
       </customHeaders>
   </httpProtocol>

La solución a la pregunta.

Si el servidor web activó la función de seguridad, puede causar un error de seguridad del lado del cliente como debería.

Shahar Shokrani avatar Sep 06 '2017 10:09 Shahar Shokrani