2009-06-04 9 views
10

Ho indagato sul codice frame breaking di recente e ho riscontrato alcuni comportamenti davvero bizzarri relativi allo same origins policy che non riesco a capire.Perché gli interruttori di frame funzionano in più domini e si possono utilizzare in modo condizionale interruttori di frame?

Supponiamo che io ho una pagina Breaker.html sul dominio A, e una pagina Container.html sul dominio B. Il codice di rompere il telaio esempio potrebbe andare in Breaker.html, come di seguito:

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

Questo interromperà Breaker.html da Container.html, ma non capisco perché dovrebbe. Dalla mia lettura della politica sulle stesse origini, top.location non dovrebbe essere accessibile in tutto, poiché Container.html si trova in un dominio diverso da Breaker.html. Ancora più strano, sembra che top.location sola scrittura:

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

Questo è problematico per me perché sto cercando di scrivere codice che permette la mia pagina di essere in un iframe, ma solo se è su lo stesso dominio del suo genitore (o si trova su un dominio consentito configurato). Tuttavia, sembra impossibile determinarlo, poiché la stessa politica sulle origini mi nega l'accesso alla sede del genitore.

Così Ho due domande, fondamentalmente:

  1. Perché la sopra Code Breaker telaio di lavoro a tutti?

  2. C'è un modo per interrompere i frame in modo condizionale, o l'unico controllo che si può fare è se top !== self? (In particolare, voglio essere in grado di leggere dominio, in modo che possa fornire un elenco di domini consentiti; semplicemente controllando se sono nello stesso dominio o no, non sarebbe l'ideale.)

risposta

1

Per la tua risposta al numero 1: in termini di sicurezza, c'è una grande differenza tra accesso in lettura e accesso in scrittura. Essere in grado di leggere top.location.href è un problema di sicurezza. Essere in grado di scrivere in top.location.href non lo è.

Per quanto riguarda la risposta alla tua domanda, non conosco il javascript abbastanza bene per essere sicuro, ma una idea sarebbe assumere che se la lettura top.location fallisce (controlla le eccezioni), è su un dominio diverso .

+0

"Lo stesso criterio di origine impedisce a un documento o uno script caricato da un'origine di ottenere ** o di impostare ** le proprietà di un documento da un'altra origine." - questo è il posto dove vengo appeso. Inoltre, ho pensato di fare il n. 2, ma voglio anche consentire agli amministratori di specificare quali domini sarebbe meglio inquadrare all'interno - Riformero la domanda. –

+1

Scrivere su top.location.href non imposta alcuna proprietà di un documento estraneo; invece, scarica il documento precedente e ne carica uno nuovo al suo posto. – eswald

+0

@Daniel: Il mio commento sulla differenza è stato pensato per essere da una prospettiva pragmatica, non da una prospettiva di specifiche tecniche. Il mio punto era che non era un problema di sicurezza legittimo e quindi era legale, piuttosto che suggerire che le specifiche dicevano che era OK. – Brian

0

La risposta alla domanda 1 è che l'operatore di uguaglianza può essere utilizzato contro top.location.href per motivi legacy. Breaker.html non può leggere top.location.href ma può confrontarlo con un altro valore.

La risposta alla domanda 2 diventa quindi no, è necessario utilizzare! == per la parte perché non sarà possibile eseguire una sottostringa su top.location.href da un cross domain breaker.html.

Potrei sbagliarmi ma questo è il mio modo di comprendere l'attuale mondo degli iframe.

0

Questo è per la domanda numero 2: se si vuole prendere HREF parent.location (non top.location), si può fare questo:

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

Fondamentalmente ciò che questo codice fa è:
[ 1] Verifica se il frame principale è quello principale perché puoi prendere solo HREF del genitore anche se non è il frame superiore.
[2] Controllare se la cronologia di iframe era vuota prima di caricare la sua origine, perché se no ... document.referrer restituirà l'ultimo HREF nella cronologia di questo frame.

Dopo di che, si dispone di un nuovo problema: in termini di valore caso di history.length è più di uno, potete utilizzare una whitelist di nomi di host per verificare se deve essere aperto o no:

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

Si noti che è un'altra opzione: è possibile utilizzare una pagina di destinazione per verificare se la "prima" pagina deve aprire o no, di questo codice:

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

Facendo in questo modo, la pagina "prima" andrà a sostituire la storia di prima (in questo caso è il primo) valore. Quel codice è inumidito "example.com" è il tuo dominio.

Problemi correlati