2009-06-04 11 views
10

He estado investigando el código frame breaking recientemente y me he encontrado con algún comportamiento realmente extraño relacionado con el same origins policy que tengo problemas para entender.¿Por qué los interruptores de cuadro funcionan con dominio cruzado y puede usar interruptores de cuadro de forma condicional?

Supongamos que tengo una página Breaker.html en el dominio A, y una página container.html en el dominio B. El ejemplo de código interruptor marco entraría en Breaker.html, como a continuación:

if (top !== self) top.location.href = self.location.href; 

Esto cortará con éxito Breaker.html fuera de Container.html, pero no entiendo por qué debería. De mi lectura de la misma política de orígenes, top.location no debería ser accesible en total, ya que Container.html está en un dominio diferente de Breaker.html. Más extraño aún, parece que top.location de sólo escritura:

// Fails if Container.html is on a different domain than Breaker.html 
alert(top.location); 

Esto es problemático porque yo estoy tratando de escribir código que permite que mi página sea en un iframe, pero sólo si es en el mismo dominio que su padre (o está en un dominio permitido configurado). Sin embargo, parece imposible determinarlo, ya que la misma política de origen me niega el acceso a la ubicación de los padres.

así que tengo dos preguntas, básicamente:

  1. ¿Por qué el interruptor anterior marco del código de trabajo en absoluto?

  2. ¿Hay alguna manera de romper marcos condicionalmente, o es el único control que uno puede hacer es si top !== self? (En particular, quiero ser capaz de leer el dominio, de modo que pueda proporcionar una lista de dominios permitidos, basta con comprobar si estoy en el mismo dominio o no, no sería lo ideal.)

Respuesta

1

Para su respuesta al número 1: en términos de seguridad, hay una gran diferencia entre el acceso de lectura y de escritura. Poder leer top.location.href es un problema de seguridad. Ser capaz de escribir en top.location.href no es.

En cuanto a la respuesta a su pregunta, no conozco el Javascript lo suficiente como para estar seguro, pero una idea sería suponer que si se lee fail top.location (verifique excepciones), está en un dominio diferente .

+0

"La misma política de origen impide que un documento o script cargado desde un origen obtenga ** o establezca ** propiedades de un documento de otro origen". - Aquí es donde me cuelgo. Además, pensé en hacer el n. ° 2, pero también quiero permitirles a los administradores especificar en qué dominios estaría bien enmarcar - Reformularé la pregunta. –

+1

Escribir en top.location.href no establece ninguna propiedad de un documento extraño; en su lugar, descarga el documento anterior y carga uno nuevo en su lugar. – eswald

+0

@Daniel: Mi comentario sobre la diferencia tenía la intención de ser desde una perspectiva pragmática, no desde una perspectiva de especificaciones técnicas. Mi punto era que no era un problema de seguridad legítimo y, por lo tanto, era legal, en lugar de sugerir que la especificación decía que estaba bien. – Brian

0

La respuesta a la pregunta 1 es que el operador de igualdad se puede usar contra top.location.href por razones heredadas. Breaker.html no puede leer top.location.href, pero puede compararlo con otro valor.

La respuesta a la pregunta 2 se convierte en no, debe usar!! = A parte porque no podrá hacer una subcadena en top.location.href desde un dominio cruzado breaker.html.

Podría estar equivocado, pero esa es mi comprensión del mundo iframe actual.

0

Esta es la pregunta número 2: Si usted quiere tomar HREF parent.location (no top.location), usted puede hacer esto:

if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer; 

Básicamente lo que hace es este código:
[ 1] Verificando si el marco principal es el superior porque puedes tomar solo el HREF de los padres incluso si no es el marco superior.
[2] Comprobando si el historial del iframe estaba en blanco antes de cargar su fuente, porque si no ... document.referrer devolverá el último HREF en este historial de marcos.

Después de eso, usted tiene un nuevo problema: en el caso del valor history.length es más de uno, se puede utilizar una lista blanca de nombres de host para comprobar si tiene que ser abierto o no:

if ([location.hostname, 'stackoverflow.com'].indexOf(location.hostname)>=0) hasToBeOpened=true; 

Tenga en cuenta que otra opción: puede utilizar una página de destino para comprobar si el "primero" de la página tiene que abrir o no, utilizar este código:

<head> 
<script> 
var parentHREF; 
if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer; 
if (/*conditions mentiones above*/) document.write("<META http-equiv='refresh' content='0;URL=http://example.com/go-here.html'>"); 
</script> 
</head> 

Hacerlo de esta manera, la página de "primera" sustituirá a la primera de la historia (en este caso es primero) valor. Ese código está asumiendo que "example.com" es tu dominio.

Cuestiones relacionadas