Superar "Pantalla prohibida por X-Frame-Options"

420

Estoy escribiendo una pequeña página web cuyo propósito es enmarcar algunas otras páginas, simplemente consolidarlas en una sola ventana del navegador para facilitar su visualización. Algunas de las páginas que estoy tratando de enmarcar prohíben que se enmarquen y arrojan un "Se niega a mostrar el documento porque la visualización está prohibida por X-Frame-Options". error en Chrome Entiendo que esta es una limitación de seguridad (por una buena razón), y no tengo acceso para cambiarla.

¿Existe algún método alternativo de encuadre o no enmarcado para mostrar páginas dentro de una sola ventana que no se active por el encabezado X-Frame-Options?

Garen Checkley
fuente
117
Si son sus páginas, elimine el limitador de cuadros. De lo contrario, respete los deseos del autor de la página y NO LOS MARQUE.
Marc B
Si recibe este error para una aplicación de Facebook y usa llamadas AJAX, leí en alguna parte que a Facebook realmente le gusta usar etiquetas # para su contacto ajax, así que intente cambiar los enlaces, funcionó para mí.
eric.itzhak
28
@MarcB Chrome y Firefox enmarcan éticamente sitios web no pertenecientes a la interfaz de usuario nativa de Chrome. Estos programas también permiten políticas relajadas del mismo origen para sus propietarios, FWIW. Como dijo Garen-Checkly: "Estoy escribiendo una pequeña página web cuyo propósito es enmarcar algunas otras páginas, simplemente consolidarlas en una sola ventana del navegador para facilitar su visualización". Eso es básicamente extender el navegador web y sería completamente ético. La intención declarada no es diferente de escribir un script bash para abrir y organizar las ventanas del navegador.
Samuel Danielson
1
Revisa Surfly . Puede hacer exactamente lo que necesita.
muodov
1
@MarcB Eso no es útil. OP podría no preocuparse por los deseos del autor de la página.
flarn2006

Respuestas:

211

Tuve un problema similar, en el que estaba tratando de mostrar contenido de nuestro propio sitio en un iframe (como un cuadro de diálogo de estilo lightbox con Colorbox ), y donde teníamos un encabezado "SAMEORIGIN de opciones de marco X" en todo el servidor servidor de origen que evita que se cargue en nuestro servidor de prueba.

Esto no parece estar documentado en ningún lado, pero si puede editar las páginas que está tratando de enmarcar (p. Ej., Son sus propias páginas), simplemente envía otro encabezado de opciones de X-Frame con cualquier cadena deshabilitada. los comandos SAMEORIGIN o DENY.

p.ej. para PHP, poniendo

<?php
    header('X-Frame-Options: GOFORIT'); 
?>

en la parte superior de su página hará que los navegadores combinen los dos, lo que da como resultado un encabezado de

X-Frame-Options SAMEORIGIN, GOFORIT

... y le permite cargar la página en un iframe. Esto parece funcionar cuando el comando SAMEORIGIN inicial se configuró a nivel de servidor y desea anularlo en un caso página por página.

¡Todo lo mejor!

Sean
fuente
3
Tenía un marco alrededor de un sitio web. En mi sitio web, estoy redirigiendo a Instagram para OAUTH. Como Instagram envía, X-Frame-Options: SAMEORIGINno hay forma de hacerlo dentro del marco. Debes usar una ventana emergente.
Steve Tauber
16
Con PHP, probablemente sea mejor usar la nueva header_removefunción, siempre que la tenga disponible (> = 5.3.0).
un gato
11
O puede editar .htaccess si desea eliminar X-Frame-Options de un directorio completo. Simplemente agregue la línea:Header always unset X-Frame-Options
Jay
44
@cawecoy: Bueno, sí, el punto es que no es válido. Se basa en navegadores que ignoran el encabezado no válido y 'fallan al abrir', que es un comportamiento no especificado y bastante dudoso para confiar. GOFORIT(u otro token no válido arbitrario aleatorio) está rompiendo deliberadamente una medida de seguridad aplicada por un servidor; si usted tiene el control del servidor usted mismo (lo que debe hacer para cualquier servicio público real), lo correcto es configurar el servidor para que no establezca el encabezado en primer lugar.
bobince
31
Esto ya no parece funcionar en Chrome. Los valores no válidos hacen que el valor predeterminado sea DENY.
jamesfm
159

Si recibe este error para un video de YouTube, en lugar de usar la URL completa, use la URL incrustada de las opciones para compartir. Se verá comohttp://www.youtube.com/embed/eCfDxZxTBW4

También puede reemplazar watch?v=con embed/lo que http://www.youtube.com/watch?v=eCfDxZxTBW4se conviertehttp://www.youtube.com/embed/eCfDxZxTBW4

Wil
fuente
14
Oh, progreso ... ¡Ojalá nos redirigieran a la página de inserción en lugar de provocar un error y hacer que reescriba mis scripts!
joeytwiddle
122

Si recibe este error al intentar incrustar un mapa de Google en un iframe, debe agregarlo &output=embedal enlace de origen.

Q Studio
fuente
120
Eso solo es cierto para incrustar mapas de Google en un iframe, y no una "solución" general.
Benjamin Wohlwend
17
Que necesitaba para insertar un mapa de Google en una caja de luz, por lo que esta "solución" era perfecto
yitwail
55
Si estás tratando de hacer esto con una intención web de Twitter, olvídalo. Acabo de perder todo el día probando diferentes plugins de lightbox solo para descubrir esto "Si bien puedes proporcionar enlaces a intentos dentro de IFRAME y widgets, las páginas resultantes no se pueden cargar en un IFRAME". Fuente: sitio web de Twitter.
Gubatron
66
Esto no funciona si está intentando cargar el iframe src después de que se cargue el resto de la página, incluso si agrega&output=embed
pathfinder
1
@pathfinder Esto funcionó para mí cuando tuve problemas para cargar el iframe src después de que se cargó la página
David Sykes
61

ACTUALIZACIÓN 2019: Usted puede by-pass X-Frame-Optionsen un <iframe>usando sólo JavaScript del lado cliente y mi X-Frame-bypass de componentes Web. Aquí hay una demostración: Hacker News en unX-Frame-Bypass . (Probado en Chrome y Firefox).

niutech
fuente
3
Esa es una solución interesante. Funciona bien en FF / Chrome / Opera, pero no funciona en IE / Edge. ¿Alguien que sepa algo que lo hará?
Coleccionista
77
Esto ya no funciona. Da "Se negó a mostrar ' news.ycombinator.com ' en un marco porque establece 'X-Frame-Options' a 'DENY'". como se esperaba
g.pickardou
2
@ g.pickardou Me funciona en Google Chrome 46, puedo ver Hacker News en un iframe.
niutech
1
@niutech ese violín funciona después de volver a cargar la página en Chrome 64, pero la primera vez que cargo la página no funciona. (Prueba de incógnito.)
Carl Walsh
1
Gracias, esto es genial!
Andrew Gans
23

Agregar un

  target='_top'

a mi enlace en la pestaña de Facebook me solucionó el problema ...

Kevin Vella
fuente
1
Tuve el mismo problema con el iframe de Paypal contenido en otro iframe. ¡Ahora funciona! Gracias
Fabrizio Fortino
44
También agregué target = '_ top', pero el problema con esta solución es que el enlace ahora se abre fuera del iframe en una nueva pestaña sin el lienzo de Facebook.
sumitkanoje
13

Tuve el mismo problema cuando intenté incrustar moodle 2 en iframe, la solución es Site administration ► Security ► HTTP securityy compruebeAllow frame embedding

Mohammad Ali Akbari
fuente
bien hecho para el método moodle, ya que los otros métodos fallan / se sobrescriben.
ericosg
7

Esta es la solución chicos !!

FB.Event.subscribe('edge.create', function(response) {
    window.top.location.href = 'url';
});

¡Lo único que funcionó para las aplicaciones de Facebook!

Konst
fuente
6

Parece que X-Frame-Options Allow-From https: // ... se deprecia y se reemplaza (y se ignora) si usa el encabezado Content-Security-Policy en su lugar.

Aquí está la referencia completa: https://content-security-policy.com/

Dr. Aaron Dishno
fuente
6

Solución para cargar un sitio web externo en un iFrame, incluso si la opción x-frame está configurada para negarse en el sitio web externo.

Si desea cargar otro sitio web en un iFrame y obtiene el Display forbidden by X-Frame-Options”error, puede superarlo creando un script proxy del lado del servidor.

El srcatributo del iFrame podría tener una URL como esta:/proxy.php?url=https://www.example.com/page&key=somekey

Entonces proxy.php se vería así:

if (isValidRequest()) {
   echo file_get_contents($_GET['url']);
}

function isValidRequest() {
    return $_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['key']) && 
    $_GET['key'] === 'somekey';
}

Esto pasa el bloque, porque es solo una solicitud GET que bien podría haber sido una visita normal a la página del navegador.

Tenga en cuenta: es posible que desee mejorar la seguridad en este script. Porque los hackers podrían comenzar a cargar páginas web a través de su script proxy.

Floris
fuente
Estaba haciendo esto hace unas semanas y cualquier URL relativa utilizada en la página externa no funciona cuando se usa echo. (Por lo general, CSS y / o JS, por lo que es posible que no obtenga la funcionalidad completa a menos que modifique las URL antes de hacer eco.) A menos que me haya perdido algo ...,
ultrageek
No estoy seguro de por qué sucede esto para usted ... Debería funcionar como una solicitud HTTP normal, tal como lo haría un usuario final al visitar la URL. Por lo tanto, el resultado de get_file_contents () debería ser una página HTML completamente funcional.
Floris
5

Intenté casi todas las sugerencias. Sin embargo, lo único que realmente resolvió el problema fue:

  1. Cree un archivo .htaccessen la misma carpeta donde se encuentra su archivo PHP.

  2. Agregue esta línea al htaccess:

    Header always unset X-Frame-Options

Incrustar el PHP por un iframe de otro dominio debería funcionar después.

Además, puede agregar al comienzo de su archivo PHP:

header('X-Frame-Options: ALLOW');

Lo cual, sin embargo, no fue necesario en mi caso.

Kai Noack
fuente
Siempre sin establecer encabezado X-Frame-Options en .htaccess hizo el truco para mí
Ujwal Dhakal
4

Tuve el mismo problema con mediawiki, esto se debió a que el servidor negó incrustar la página en un iframe por razones de seguridad.

Lo resolví escribiendo

$wgEditPageFrameOptions = "SAMEORIGIN"; 

en el archivo de configuración de mediawiki php.

Espero eso ayude.

John White
fuente
3

FWIW:

Tuvimos una situación en la que necesitábamos matar nuestro iFramecuando apareció este código de "interruptor". Entonces, usé el PHP function get_headers($url);para verificar la URL remota antes de mostrarla en un iFrame. Para un mejor rendimiento, almacené en caché los resultados en un archivo, por lo que no estaba haciendo una conexión HTTP cada vez.

Zane Claes
fuente
3

Estaba usando Tomcat 8.0.30, ninguna de las sugerencias me funcionó. Como estamos buscando actualizar X-Frame-Optionsy configurarlo ALLOW, así es como lo configuré para permitir iframes incrustados:

  • Navegue al directorio conf de Tomcat, edite el archivo web.xml
  • Agregue el siguiente filtro:
<filter>
            <filter-name>httpHeaderSecurity</filter-name>
            <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
                   <init-param>
                           <param-name>hstsEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingEnabled</param-name>
                           <param-value>true</param-value>
                   </init-param>
                   <init-param>
                           <param-name>antiClickJackingOption</param-name>
                           <param-value>ALLOW-FROM</param-value>
                   </init-param>
            <async-supported>true</async-supported>
       </filter>

       <filter-mapping>
                   <filter-name>httpHeaderSecurity</filter-name>
                   <url-pattern>/*</url-pattern>
                   <dispatcher>REQUEST</dispatcher>
       </filter-mapping> 
  • Reiniciar el servicio Tomcat
  • Acceda a los recursos utilizando un iFrame.
Giri
fuente
2

La única pregunta que tiene muchas respuestas. Bienvenido a la guía que desearía tener cuando estaba luchando por esto para que funcionara a las 10:30 de la noche del día de la fecha límite ... FB hace algunas cosas raras con las aplicaciones de lienzo, y bueno, te han advertido. Si todavía está aquí y tiene una aplicación Rails que aparecerá detrás de un lienzo de Facebook, necesitará:

Gemfile:

gem "rack-facebook-signed-request", :git => 'git://github.com/cmer/rack-facebook-signed-request.git'

config / facebook.yml

facebook:
  key: "123123123123"
  secret: "123123123123123123secret12312"

config / application.rb

config.middleware.use Rack::Facebook::SignedRequest, app_id: "123123123123", secret: "123123123123123123secret12312", inject_facebook: false

config / initializers / omniauth.rb

OmniAuth.config.logger = Rails.logger
SERVICES = YAML.load(File.open("#{::Rails.root}/config/oauth.yml").read)
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, SERVICES['facebook']['key'], SERVICES['facebook']['secret'], iframe:   true
end

application_controller.rb

before_filter :add_xframe
def add_xframe
  headers['X-Frame-Options'] = 'GOFORIT'
end

Necesita un controlador para llamar desde la configuración del lienzo de Facebook, utilicé /canvas/e hice que la ruta fuera la principal SiteControllerpara esta aplicación:


class SiteController < ApplicationController
  def index
    @user = User.new
  end
  def canvas
    redirect_to '/auth/failure' if request.params['error'] == 'access_denied'
    url = params['code'] ? "/auth/facebook?signed_request=#{params['signed_request']}&state=canvas" : "/login"
    redirect_to url
  end
  def login
  end
end

login.html.erb


<% content_for :javascript do %>
  var oauth_url = 'https://www.facebook.com/dialog/oauth/';
  oauth_url += '?client_id=471466299609256';
  oauth_url += '&redirect_uri=' + encodeURIComponent('https://apps.facebook.com/wellbeingtracker/');
  oauth_url += '&scope=email,status_update,publish_stream';
console.log(oauth_url);
  top.location.href = oauth_url;
<% end %>

Fuentes

  • La configuración creo que vino del ejemplo de omniauth.
  • El archivo de gemas (que es clave !!!) vino de: slideshare cosas que aprendí ...
  • Esta pregunta de la pila tenía todo el ángulo Xframe, por lo que obtendrá un espacio en blanco, si no coloca este encabezado en el controlador de la aplicación.
  • Y mi hombre @rafmagana escribió esta guía de heroku , que ahora puedes adoptar para los rieles con esta respuesta y los hombros de gigantes con los que caminas.
pjammer
fuente
2

target = '_ parent'

Utilizando la idea de Kevin Vella, intenté agregar ese atributo para formar elementos creados por el generador de botones de PayPal. Me funcionó para que Paypal no se abra en una nueva ventana / pestaña del navegador.

jiminikiz
fuente
Lamentablemente, esto tampoco parece funcionar para un safari.
Wtower
1

No estoy seguro de cuán relevante es, pero construí una solución para esto. En mi sitio, quería mostrar el enlace en una ventana modal que contenía un iframe que carga la URL.

Lo que hice fue vincular el evento de clic del enlace a esta función de JavaScript. Todo esto hace una solicitud a un archivo PHP que verifica las cabeceras de URL para las opciones de X-FRAME antes de decidir si cargar la URL dentro de la ventana modal o redirigir.

Aquí está la función:

  function opentheater(link, title){
        $.get( "url_origin_helper.php?url="+encodeURIComponent(link), function( data ) {
  if(data == "ya"){
      $(".modal-title").html("<h3 style='color:480060;'>"+title+"&nbsp;&nbsp;&nbsp;<small>"+link+"</small></h3>");
        $("#linkcontent").attr("src", link);
        $("#myModal").modal("show");
  }
  else{
      window.location.href = link;
      //alert(data);
  }
});


        }

Aquí está el código del archivo PHP que lo comprueba:

<?php
$url = rawurldecode($_REQUEST['url']);
$header = get_headers($url, 1);
if(array_key_exists("X-Frame-Options", $header)){
    echo "nein";
}
else{
    echo "ya";
}


?>

Espero que esto ayude.

swatkat7
fuente
1

Me encontré con este problema al ejecutar un sitio web de WordPress. Intenté todo tipo de cosas para solucionarlo y no estaba seguro de cómo, en última instancia, el problema era porque estaba usando el reenvío de DNS con enmascaramiento, y los enlaces a sitios externos no se abordaban correctamente. es decir, mi sitio estaba alojado en http: //123.456.789/index.html pero estaba enmascarado para ejecutarse en http://somewebSite.com/index.html . Cuando ingresé http: //123.456.789/index.html en el navegador, al hacer clic en esos mismos enlaces no surgieron problemas de origen de cuadros X en la consola JS, pero se ejecutó http://somewebSite.com/index.html hice. Para enmascarar correctamente, debe agregar los servidores de nombres DNS de su host a su servicio de dominio, es decir, godaddy.com debe tener servidores de nombres, por ejemplo, ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, si fuera utilizando digitalocean.com como su servicio de alojamiento.

kinghenry14
fuente
1
Terminé haciendo: remove_action( 'admin_init', 'send_frame_options_header',10);evitar este problema ...
majick
1

Es sorprendente que nadie aquí haya mencionado Apachela configuración del servidor ( *.confarchivos) o el .htaccessarchivo en sí mismo como causa de este error. Buscar a través de sus .htaccesso Apachearchivos de configuración, asegurándose de que usted no tiene el siguiente conjunto de DENY:

Header always set X-Frame-Options DENY

Al cambiarlo a SAMEORIGIN, las cosas funcionan como se espera:

Header always set X-Frame-Options SAMEORIGIN

Ilia Rostovtsev
fuente
se mencionó antes: vea el comentario de @Jay en la respuesta stackoverflow.com/a/6767901/1875965
Sandra
Config. El archivo .conf Encabezado siempre establece X-Frame-Options SAMEORIGIN!
GeekHades
Pero, ¿cómo es esto relevante para la pregunta aquí, donde el encabezado proviene de servidores extranjeros , directamente al cliente , si su propio servidor ni siquiera está involucrado? ¿Me estoy perdiendo de algo?
Sz.
1

La única respuesta real, si no controla los encabezados en su fuente que desea en su iframe, es usar un proxy. Haga que un servidor actúe como cliente, reciba la fuente, elimine los encabezados problemáticos, agregue CORS si es necesario y luego haga ping a su propio servidor.

Hay otra respuesta que explica cómo escribir tal proxy. No es difícil, pero estaba seguro de que alguien tuvo que haber hecho esto antes. Era difícil encontrarlo, por alguna razón.

Finalmente encontré algunas fuentes:

https://github.com/Rob--W/cors-anywhere/#documentation

^ preferido. Si necesita un uso raro, creo que puede usar su aplicación heroku. De lo contrario, es código ejecutarlo usted mismo en su propio servidor. Tenga en cuenta cuáles son los límites.

whateverorigin.org

^ segunda opción, pero bastante antigua. opción supuestamente más nueva en python: https://github.com/Eiledon/alloworigin

entonces hay la tercera opción:

http://anyorigin.com/

Lo que parece permitir un poco de uso gratuito, pero lo colocará en una lista pública de vergüenza si no paga y usa una cantidad no especificada, de la que solo puede ser eliminado si paga la tarifa ...

Kyle Baker
fuente
0

No se menciona pero puede ayudar en algunos casos:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write(xhr.responseText);
        doc.close();
    }
}
xhr.open('GET', url, true);
xhr.send(null);
mattdlockyer
fuente
0

Use esta línea dada a continuación en lugar de la header()función.

echo "<script>window.top.location = 'https://apps.facebook.com/yourappnamespace/';</script>";
Hemanta Nandi
fuente
0

Tuve este problema y lo resolví editando httd.conf

<IfModule headers_module>
    <IfVersion >= 2.4.7 >
        Header always setifempty X-Frame-Options GOFORIT
    </IfVersion>
    <IfVersion < 2.4.7 >
        Header always merge X-Frame-Options GOFORIT
    </IfVersion>
</IfModule>

Cambié SAMEORIGIN a GOFORIT y reinicié el servidor

Arthur Tsidkilov
fuente
-1

Pruebe esto, no creo que nadie haya sugerido esto en el tema, esto resolverá como el 70% de su problema, para algunas otras páginas, debe descartarlo, tengo la solución completa pero no para el público,

AGREGAR a continuación a su iframe

sandbox = "allow-same-origin allow-scripts allow-popups allow-forms"

Zulqurnain abbas
fuente
1
el sandboxing reduce los privilegios, no los agrega. ver html5rocks.com/en/tutorials/security/sandboxed-iframes
Kyle Baker el