2009-06-04 7 views
10

Ich habe kürzlich Code frame breaking untersucht und bin auf einige wirklich seltsame Verhalten im Zusammenhang mit der same origins policy, die ich habe Probleme zu verstehen.Warum funktionieren Frame Breaker domänenübergreifend und können Sie Frame Breaker bedingt verwenden?

nehme ich eine Seite Breaker.html auf Domäne A haben, und eine Seite Container.html auf Domäne B Das Beispiel Rahmen Brecher Code würde in Breaker.html gehen, wie unten:

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

Dies wird Breaker.html erfolgreich aus Container.html entfernen, aber ich verstehe nicht, warum es so sein sollte. Von meiner Richtlinie zum Lesen derselben Herkunft sollte top.location nicht zugänglich sein überhaupt, da Container.html auf einer anderen Domäne als Breaker.html ist. Auch eigenartiger scheint es, dass top.location write-only:

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

Dies ist für mich problematisch, weil ich versuche, Code zu schreiben, meine Seite in einem Iframe sein kann, aber nur, wenn es auf die gleiche Domäne wie das übergeordnete Element (oder auf einer konfigurierten zulässigen Domäne). Es scheint jedoch unmöglich zu sein, dies zu bestimmen, da die Politik der gleichen Herkunft mir den Zugang zum Aufenthaltsort der Eltern verweigert.

Also habe ich zwei Fragen bekommt, im Grunde:

  1. Warum wird die oben gar breaker Coderahmen Arbeit?

  2. Gibt es eine Möglichkeit, Rahmen bedingt zu brechen, oder ist die einzige Prüfung, die man tun kann, ob top !== self? (Insbesondere mag ich in der Lage sein, die Domain zu lesen, so dass ich eine Liste der zulässigen Domains zur Verfügung stellen kann, einfach zu überprüfen, ob ich in der gleichen Domäne bin oder nicht wäre nicht ideal.)

Antwort

1

Für Ihre Antwort auf Nummer 1: In Bezug auf die Sicherheit gibt es einen großen Unterschied zwischen Lesezugriff und Schreibzugriff. Top.location.href lesen zu können ist ein Sicherheitsproblem. In der Lage schreiben nach top.location.href ist nicht.

Wie für die Antwort auf Ihre Frage, ich weiß Javascript nicht gut genug, um sicher zu sein, aber eine Idee wäre, wenn das Lesen top.location schlägt fehl (auf Ausnahmen überprüfen), ist es auf einer anderen Domäne .

+0

"Die gleiche Ursprungsrichtlinie verhindert, dass ein Dokument oder Skript, das von einem Ursprung geladen wurde, ** Eigenschaften eines Dokuments von einem anderen Ursprung erhält ** oder setzt." - hier werde ich aufgehängt. Außerdem habe ich darüber nachgedacht, # 2 zu machen, aber ich möchte auch zulassen, dass Admins angeben, in welchen Domains es in Ordnung wäre, dass sie darin enthalten sind - ich werde die Frage neu formulieren. –

+1

Das Schreiben in top.location.href legt keine Eigenschaften eines fremden Dokuments fest; Stattdessen wird das vorherige Dokument entladen und stattdessen ein neues geladen. – eswald

+0

@Daniel: Mein Kommentar zu dem Unterschied sollte aus einer pragmatischen Perspektive stammen, nicht aus einer technischen Spezifikationsperspektive. Mein Punkt war, dass es kein legitimes Sicherheitsproblem war und daher legal war, anstatt darauf hinzuweisen, dass die Spezifikation es für OK hielt. – Brian

0

Die Antwort auf Frage 1 ist, dass der Gleichheitsoperator aus Legacy-Gründen gegen top.location.href verwendet werden kann. Breaker.html kann top.location.href nicht lesen, aber es kann es mit einem anderen Wert vergleichen.

Die Antwort auf Frage 2 wird dann nein, Sie müssen die! == zu Teil verwenden, weil Sie nicht in der Lage sein werden, einen Teilstring on top.location.href von einem Cross Domain Breaker.html zu tun.

Ich könnte falsch liegen, aber das ist mein Verständnis der aktuellen Iframe-Welt.

0

Dies ist für Frage Nummer 2: Wenn Sie HREF von parent.location nehmen wollen (nicht top.location), können Sie dies tun:

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

Grundsätzlich ist dieser Code, was tut, ist:
[ 1] Überprüfen, ob der übergeordnete Rahmen der oberste ist, da Sie nur den HREF des übergeordneten Elements verwenden können, auch wenn es nicht der oberste Frame ist.
[2] Überprüfen, ob der iframe-Verlauf leer war, bevor er seine Quelle geladen hat, denn wenn nicht ... wird document.referrer den letzten HREF in diesem Frame-Verlauf zurückgeben.

Danach müssen Sie ein neues Problem: Wert Fall history.length mehr als einer ist, können Sie eine weiße Liste von Host-Namen verwenden können, um zu überprüfen, ob es oder nicht geöffnet werden muss:

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

Beachten Sie, dass Sie eine weitere Option: wenn die kann eine Zielseite, um zu überprüfen „erste“ Seite zu öffnen oder nicht hat, verwenden sie diesen Code:

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

es auf diese Weise tun, die „erste“ Seite Geschichte ersetzen wird zunächst (in diesem Fall ist es zuerst) Wert. Dieser Code bedeutet, dass "example.com" Ihre Domain ist.