iframe - sameorigin - Superación de "Visualización prohibida por X-Frame-Options"
x-frame-options java (25)
Estoy escribiendo una pequeña página web cuyo propósito es enmarcar algunas otras páginas, simplemente para consolidarlas en una sola ventana del navegador para facilitar la visualización. Algunas de las páginas que estoy intentando encuadrar prohíben ser enmarcadas y lanzan un "Se niega a mostrar el documento porque la pantalla está prohibida por X-Frame-Options". error en Chrome. Entiendo que esto es una limitación de seguridad (por una buena razón) y no tengo acceso para cambiarla.
¿Hay algún método alternativo de enmarcado o no enmarcado para mostrar páginas dentro de una sola ventana que no se vea afectado por el encabezado de Opciones de X-Frame?
Añadiendo un
target=''_top''
a mi enlace en la pestaña de facebook solucioné el problema para mí ...
Es sorprendente que nadie haya mencionado la configuración del servidor Apache
(archivos *.conf
) o el archivo .htaccess
como la causa de este error. Busque a través de sus archivos de configuración .htaccess
o Apache
, asegurándose de que no tenga el siguiente conjunto para DENY
:
Header always set X-Frame-Options DENY
Al SAMEORIGIN
a SAMEORIGIN
, las cosas funcionan como se espera:
Header always set X-Frame-Options SAMEORIGIN
Esta es la solución chicos !!
FB.Event.subscribe(''edge.create'', function(response) {
window.top.location.href = ''url'';
});
Lo único que funcionó para aplicaciones de facebook!
Estaba usando Tomcat 8.0.30, ninguna de las sugerencias funcionó para mí. Mientras buscamos actualizar X-Frame-Options
y establecerlo en ALLOW
, aquí está cómo configuré para permitir incrustar iframes:
- 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>
- Reinicie el servicio Tomcat
- Accede a los recursos utilizando un iFrame.
FWIW:
Tuvimos una situación en la que teníamos que matar nuestro iFrame
cuando apareció este código de "interruptor". Entonces, usé la function get_headers($url);
PHP function get_headers($url);
para revisar la URL remota antes de mostrarla en un iFrame
. Para un mejor rendimiento, guardé en caché los resultados en un archivo, por lo que no estaba haciendo una conexión HTTP cada vez.
Hay un complemento para Chrome que elimina la entrada del encabezado (solo para uso personal):
Intente esto, no creo que nadie sugiriera esto en el tema, esto se resolverá como el 70% de su problema, para algunas otras páginas, tiene que descartar, tengo la solución completa pero no para el público,
AGREGUE a continuación a su iframe
sandbox = "allow-same-origin-allow scripts allow-popups allow-forms"
La única pregunta que tiene un montón de respuestas. Bienvenido a la guía que desearía tener cuando estaba luchando por hacer esto para que funcionara a las 10:30 de la noche del día de la fecha límite ... FB hace algunas cosas extrañas con las aplicaciones de lienzo, y bueno, has sido advertido. Si todavía estás aquí y tienes una aplicación Rails que aparecerá detrás de un Facebook Canvas, necesitarás:
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
Necesitas un controlador para llamar desde la configuración del lienzo de Facebook, usé /canvas/
e hice que la ruta fuera al SiteController
de SiteController
principal para 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 !!!) proviene de: compartir cosas que aprendí ...
- Esta pregunta de la pila tenía todo el ángulo de Xframe, por lo que obtendrás un espacio en blanco, si no pones este encabezado en el controlador de la aplicación.
- Y mi hombre, @rafmagana, escribió esta guía heroku , que ahora puedes adoptar para los carriles con esta respuesta y los hombros de gigantes en los que caminas.
La única respuesta real, si no controla los encabezados de su fuente que desea en su iframe, es proxy. Haga que un servidor actúe como un 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 un proxy de este tipo. No es difícil, pero estaba seguro de que alguien tenía 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 necesitas un uso raro, creo que puedes usar su aplicación heroku. De lo contrario, es el código para ejecutarlo usted mismo en su propio servidor. Tenga en cuenta cuáles son los límites.
whateverorigin.org
Segunda opción, pero bastante antigua. supuestamente nueva elección en python: https://github.com/Eiledon/alloworigin
Luego está la tercera opción:
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 cual solo puede ser eliminado si paga la tarifa ...
Me encontré con este problema cuando se ejecuta un sitio web de wordpress. Intenté todo tipo de cosas para solucionarlo y no estaba seguro de cómo, en última instancia, el problema se debía a que estaba usando el reenvío de DNS con enmascaramiento y los enlaces a sitios externos no se estaban abordando 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 http://123.456.789/index.html en el navegador, al hacer clic en esos mismos enlaces no hubo problemas con los orígenes de X-frame en la consola JS, pero si se ejecutó http://somewebSite.com/index.html . 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 de ejemplo, ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com, si estuviera Utilizando digitalocean.com como tu servicio de hosting.
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 es vincular el evento de clic del enlace a esta función javascript. Todo lo que hace es hacer una solicitud a un archivo PHP que comprueba los encabezados de las URL para X-FRAME-Options 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+" <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 verifica:
<?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.
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);
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/
Probé casi todas las sugerencias. Sin embargo, lo único que realmente resolvió el problema fue:
Cree un archivo
.htaccess
en la misma carpeta donde se encuentra su archivo PHP.Agrega 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, podría agregar al principio de su archivo PHP:
header(''X-Frame-Options: ALLOW'');
Lo cual, sin embargo, no era necesario en mi caso.
Puede omitir X-Frame-Options
en un <iframe>
usando solo JavaScript del lado del cliente y YQL . Aquí hay una prueba de concepto: Hacker News en un <iframe>
. (Probado en Chrome y Firefox; si no funciona, intente actualizar la página).
El proceso es el siguiente:
- Solicitar una URL iframe de YQL (función
loadURL
), - Obtenga datos HTML de YQL (función
getData
), - Agregue un
<base link>
y un<script>
cargando enlaces en un iframe usando YQL también, - Inyecte este HTML en un
<iframe>
vacío (funciónloadHTML
).
El código JS de muestra:
var iframe = document.getElementsByTagName(''iframe'')[0];
var url = iframe.src;
var getData = function (data) {
if (data && data.query && data.query.results && data.query.results.resources && data.query.results.resources.content && data.query.results.resources.status == 200) loadHTML(data.query.results.resources.content);
else if (data && data.error && data.error.description) loadHTML(data.error.description);
else loadHTML(''Error: Cannot load '' + url);
};
var loadURL = function (src) {
url = src;
var script = document.createElement(''script'');
script.src = ''https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22'' + encodeURIComponent(url) + ''%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=getData'';
document.body.appendChild(script);
};
var loadHTML = function (html) {
iframe.src = ''about:blank'';
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html.replace(/<head>/i, ''<head><base href="'' + url + ''"><scr'' + ''ipt>document.addEventListener("click", function(e) { if(e.target && e.target.nodeName == "A") { e.preventDefault(); parent.loadURL(e.target.href); } });</scr'' + ''ipt>''));
iframe.contentWindow.document.close();
}
loadURL(iframe.src);
Si está recibiendo este error al intentar incrustar contenido de Vimeo, cambie el src del iframe,
desde: https://vimeo.com/63534746
a: http://player.vimeo.com/video/63534746
Si recibe este error al intentar incrustar un mapa de Google en un iframe
, debe agregar &output=embed
en el enlace de origen.
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á como http://www.youtube.com/embed/eCfDxZxTBW4
También puede reemplazar watch?v=
con embed/
so http://www.youtube.com/watch?v=eCfDxZxTBW4
convierte en http://www.youtube.com/embed/eCfDxZxTBW4
Tuve el mismo problema con mediawiki, esto se debió a que el servidor denegó la incrustación de la página en un iframe por razones de seguridad.
Lo resolví escribiendo
$wgEditPageFrameOptions = "SAMEORIGIN";
en el archivo de configuración php de mediawiki.
Espero eso ayude.
Tuve el mismo problema cuando intenté incrustar moodle 2 en iframe, la solución es Site administration ► Security ► HTTP security
y marque Allow frame embedding
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
Tuve un problema similar, cuando intentaba mostrar contenido de nuestro sitio en un iframe (como un cuadro de diálogo de estilo lightbox con Colorbox ), y donde teníamos un encabezado "X-Frame-Options SAMEORIGIN" en todo el servidor en el servidor de origen que evita que se cargue en nuestro servidor de prueba.
Esto no parece estar documentado en ninguna parte, pero si puede editar las páginas que está tratando de forrame (por ejemplo, son sus propias páginas), simplemente envíe otro encabezado de Opciones de X-Frame con cualquier cadena en todo deshabilitado 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 resulta en 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 le gustaría anularlo en un caso página por página.
¡Todo lo mejor!
Use esta línea dada a continuación en lugar de la función de header()
.
echo "<script>window.top.location = ''https://apps.facebook.com/yourappnamespace/'';</script>";
Solución para cargar un sitio web externo en un iFrame, incluso si la opción x-frame está configurada para negar en el sitio web externo.
Si desea cargar otro sitio web en un iFrame y aparece el error Display forbidden by X-Frame-Options”
entonces puede superarlo creando un script proxy del lado del servidor.
El atributo src
del iFrame podría tener una URL parecida a esta: /proxy.php?url=https://www.example.com/page&key=somekey
Entonces proxy.php se vería algo así como:
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 ordinaria 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.
target = ''_ padre''
Usando 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.