Comment empêcher IFRAME de rediriger la fenêtre de niveau supérieur

133

Certains sites Web ont du code pour «sortir» des IFRAMEenclos, ce qui signifie que si une page Aest chargée en tant que IFRAMEpage parente à l'intérieur d'une page parente, Pdu Javascript Aredirige la fenêtre externe vers A.

Typiquement, ce Javascript ressemble à ceci:

<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;
</script>

Ma question est la suivante: en tant qu'auteur de la page parente Pet n'étant pas l'auteur de la page intérieure A, comment puis-je éviter Ade faire ce break-out?

PS Il me semble que cela devrait être une violation de sécurité intersite, mais ce n'est pas le cas.

Jason Cohen
la source
Je ne pense pas que vous puissiez faire grand-chose du tout ... si vous n'êtes pas l'auteur du contenu du cadre.
scunliffe

Réponses:

43

Essayez d'utiliser la propriété onbeforeunload, qui permettra à l'utilisateur de choisir s'il souhaite quitter la page.

Exemple: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

En HTML5, vous pouvez utiliser la propriété sandbox. Veuillez voir la réponse de Pankrat ci-dessous. http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

fasih.rana
la source
1
Cependant, les iFrames permettent la communication entre domaines, en utilisant postMessage. Ce n'est pas un risque pour la sécurité, mais quelqu'un voudra peut-être savoir que cette fonctionnalité existe lorsqu'il verra votre commentaire. :)
coreyward
Ce n'était pas possible au moment de la rédaction de cette réponse. Je vous remercie de le faire remarquer.
fasih.rana
@SirDarius pourriez-vous s'il vous plaît montrer un exemple, très apprécié.
user198989
L'utilisateur ne saura pas pourquoi cette confirmation apparaît et sélectionnera probablement une réponse aléatoire. Je ne recommande pas de l'utiliser. Il existe d'autres solutions: le sandbox.
oriadam
1
@ fasih.rana Le deuxième article m'a beaucoup aidé. Merci;)
MrD
127

Avec HTML5, l' attribut iframe sandbox a été ajouté. Au moment d'écrire ces lignes, cela fonctionne sur Chrome, Safari, Firefox et les versions récentes d'IE et d'Opera, mais fait à peu près ce que vous voulez:

<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

Si vous souhaitez autoriser les redirections de niveau supérieur, spécifiez sandbox="allow-top-navigation".

Pankrat
la source
attends quoi? Ils vous ont laissé faire ça? Je pensais que si un site Web voulait éclater, tous les navigateurs le laisseraient. Comment les gens sont-ils censés garder leur site Web hors des iframes avec cela? Je ne me plains pas, génial.
Farzher
1
@StephenSarcsamKamenar Si vous souhaitez protéger votre site contre l'affichage dans iframe, l'en - tête X-Frame-Options est disponible avec la valeur SAMEORIGIN . La plupart des navigateurs modernes n'afficheront pas le site dans l'iframe avec cet en-tête.
Grzegorz
4
Malheureusement, sandboxn'autorise pas Flash ou tout autre type d'objet dans le cadre en bac à sable, ce qui rend la sandboxfonctionnalité inutile dans de nombreux cas.
oriadam
1
Les sites Web ne doivent pas «éclater» pour protester contre leur inclusion dans une iframe. Ils peuvent simplement afficher un message ou rester vides. Malheureusement, autoriser l'exécution de scripts dans l'iframe vous ouvre toujours à une iframe non autorisée faisant while (1) {} et d'autres boucles infinies. Je souhaite que chaque iframe puisse avoir son propre fil.
Gregory Magarshak
51

J'utilise sandbox = "..."

  • allow-forms permet la soumission de formulaire
  • allow-popups autorise les popups
  • allow-pointer-lock permet le verrouillage du pointeur
  • allow-same-origin permet au document de conserver son origine
  • allow-scripts permet l'exécution de JavaScript et permet également aux fonctionnalités de se déclencher automatiquement
  • allow-top-navigation permet au document de sortir du cadre en naviguant dans la fenêtre de niveau supérieur

La navigation par le haut est ce que vous voulez éviter, alors laissez-la de côté et elle ne sera pas autorisée. Tout ce qui est laissé de côté sera bloqué

ex.

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>
adigioia
la source
3
Notez que Flash (et tout autre objet) sera également bloqué, sans possibilité de l'autoriser. Cette "fonctionnalité de sécurité" m'empêche d'utiliser le bac à sable tous ensemble
oriadam
4

Je sais que cela fait longtemps que la question n'a pas été posée, mais voici ma version améliorée, elle attendra 500 ms pour tout appel ultérieur uniquement lorsque l'iframe sera chargé.

<script type="text/javasript">
var prevent_bust = false ;
    var from_loading_204 = false;
    var frame_loading = false;
    var prevent_bust_timer = 0;
    var  primer = true;
    window.onbeforeunload = function(event) {
        prevent_bust = !from_loading_204 && frame_loading;
        if(from_loading_204)from_loading_204 = false;
        if(prevent_bust){
            prevent_bust_timer=500;
        }
    }
    function frameLoad(){
        if(!primer){
            from_loading_204 = true;
            window.top.location = '/?204';
            prevent_bust = false;
            frame_loading = true;
            prevent_bust_timer=1000;
        }else{
            primer = false;
        }
    }
    setInterval(function() {  
        if (prevent_bust_timer>0) {  
            if(prevent_bust){
                from_loading_204 = true;
                window.top.location = '/?204';
                prevent_bust = false;
            }else if(prevent_bust_timer == 1){
                frame_loading = false;
                prevent_bust = false;
                from_loading_204 = false;
                prevent_bust_timer == 0;
            }



        }
        prevent_bust_timer--;
        if(prevent_bust_timer==-100) {
            prevent_bust_timer = 0;
        }
    }, 1);
</script>

et onload="frameLoad()"et onreadystatechange="frameLoad();"doivent être ajoutés au cadre ou à l'iframe.

Luis Deleon
la source
2

Étant donné que la page que vous chargez à l'intérieur de l'iframe peut exécuter le code "break out" avec un setInterval, onbeforeunload peut ne pas être aussi pratique, car il pourrait flouter l'utilisateur avec "Êtes-vous sûr de vouloir partir?" dialogues.

Il existe également l'attribut de sécurité iframe qui ne fonctionne que sur IE et Opera

:(

user47087
la source
2

Dans mon cas, je souhaite que l'utilisateur visite la page interne afin que le serveur voie son adresse IP en tant que visiteur. Si j'utilise la technique du proxy php, je pense que la page interne verra mon IP de serveur en tant que visiteur, donc ce n'est pas bon. La seule solution que j'ai trouvée jusqu'à présent est wilth onbeforeunload. Mettez ceci sur votre page:

<script type="text/javascript">
    window.onbeforeunload = function () {                       
         return "This will end your session";
    }
</script>

Cela fonctionne à la fois dans Firefox et c'est à dire, c'est ce que j'ai testé. vous trouverez des versions utilisant quelque chose comme evt.return (peu importe) merde ... qui ne fonctionne pas dans Firefox.

radu
la source
0

Ce faisant, vous pourrez contrôler toute action de la page encadrée, ce que vous ne pouvez pas. La politique d'origine du même domaine s'applique.

Diodeus - James MacFarlane
la source
20
Je ne demande pas de contrôler ce qu'il y a à l'intérieur de l'IFRAME. Je demande d' empêcher ce qu'il y a à l'intérieur de l'IFRAME de me contrôler.
Jason Cohen