436 votes

Frame Buster Buster ... code buster nécessaire

Disons que vous ne voulez pas que d'autres sites "encadrent" votre site dans une page d'accueil. <iframe> :

<iframe src="http://example.org"></iframe>

Vous insérez donc du JavaScript anti-cadrage dans toutes vos pages :

/* break us out of any containing iframes */
if (top != self) { top.location.replace(self.location.href); }

Excellent ! Désormais, vous sortez automatiquement des iframes qu'ils contiennent. Sauf pour un petit problème.

Il s'avère que.., votre code anti-cadres peut être cassé , comme indiqué ici :

<script type="text/javascript">
    var prevent_bust = 0  
    window.onbeforeunload = function() { prevent_bust++ }  
    setInterval(function() {  
      if (prevent_bust > 0) {  
        prevent_bust -= 2  
        window.top.location = 'http://example.org/page-which-responds-with-204'  
      }  
    }, 1)  
</script>

Ce code effectue les opérations suivantes :

  • incrémente un compteur à chaque fois que le navigateur tente de naviguer hors de la page en cours, par l'intermédiaire de la fonction window.onbeforeunload gestionnaire d'événements
  • met en place une minuterie qui se déclenche toutes les millisecondes via setInterval() et s'il voit le compteur incrémenté, il change l'emplacement actuel pour un serveur contrôlé par l'attaquant
  • ce serveur envoie une page avec le code d'état HTTP 204 qui ne permet pas au navigateur de naviguer n'importe où

Ma question est la suivante - et il s'agit plus d'un puzzle JavaScript que d'une véritable problème -- Comment vaincre le destructeur de cadres ?

J'ai eu quelques idées, mais rien n'a fonctionné lors de mes tests :

  • en essayant d'effacer le onbeforeunload événement via onbeforeunload = null n'a pas eu d'effet
  • l'ajout d'un alert() a arrêté le processus, ce qui a permis à l'utilisateur de savoir ce qui se passait, mais n'a pas interféré avec le code de quelque manière que ce soit ; en cliquant sur OK, le processus se poursuit normalement.
  • Je ne vois aucun moyen d'effacer la setInterval() minuterie

Je ne suis pas vraiment un programmeur JavaScript, alors voici le défi que je vous lance : hey buster, peux-tu casser le cadre buster ?

0 votes

Je n'ai pas les moyens de tester cela pour le moment, mais il semble que la seule façon de bloquer le minuteur très rapide de la page d'accueil soit de bloquer activement l'unique thread javascript du navigateur avec une boucle infinie. Ce que je ne sais pas, c'est si le navigateur sera capable de recharger la page du haut pendant que cela se passe. top.location.replace(self.location.href) ; while(true) { }

16 votes

Matt, le code "frame-buster-buster" posté ci-dessus définitivement œuvre. Un euh ami m'en a parlé Ou quelque chose comme ça :)

0 votes

... comme utiliser <body onbeforeunload="prevent_bust++"> au lieu de window.onbeforeunload ou quelque chose comme ça ;]

210voto

6 votes

Excellent, la prise en charge dans le navigateur .exe est sans aucun doute la meilleure façon de procéder. Quand vous dites "la plupart des navigateurs", lesquels précisément ? Je n'arrive pas à trouver de bonnes sources pour autre chose qu'IE8.

2 votes

Voici une page de test : enhanceie.com/test/clickjack . Chrome 4.1.249.1042 supporte. Opera 10.50 est compatible. Firefox 3.6.2 n'est pas encore compatible. Safari 4.0.3 est compatible.

1 votes

Firefox 3.6.9 le supportera nativement ( hackademix.net/2010/08/31/… ) et toute installation de Firefox avec NoScript l'a depuis le début de l'année 2009 ( hackademix.net/2009/01/29/x-frame-options-in-firefox )

149voto

Hugoware Points 13645

Je ne sais pas si c'est viable ou non - mais si vous ne pouvez pas briser le cadre, pourquoi ne pas simplement afficher un avertissement. Par exemple, si votre page n'est pas la "première page", créez une méthode setInterval qui tente de briser le cadre. Si après 3 ou 4 tentatives, votre page n'est toujours pas la première page, créez un élément div qui couvre toute la page (boîte modale) avec un message et un lien comme...

Vous visualisez cette page dans une fenêtre non autorisée - (Blah blah... problème de sécurité potentiel)

cliquez sur ce lien pour résoudre ce problème

Ce n'est pas la meilleure solution, mais je ne vois pas comment ils pourraient script s'en sortir.

2 votes

J'ai essayé et cela fonctionne. Un autre aspect que j'apprécie dans cette solution est qu'elle permet à l'utilisateur de savoir sur quel type de site il se trouvait avant d'accéder à votre contenu. Exemple de code : if (parent.frames.length > 0) { top.location.replace(document.location) ; setTimeout(function() { if (parent.frames.length > 0) { document.location = " google.com " ; } }, 10) ; }

0 votes

C'est non seulement un bon moyen d'éviter les abus, mais c'est aussi une bonne chose pour les sites qui voudraient s'insérer dans votre site pour y jeter un coup d'œil, mais pas pour en permettre l'utilisation. Idéalement, je pense qu'il faudrait utiliser une capture d'écran de la page d'accueil du site, en expliquant pourquoi il ne peut pas être utilisé dans l'iframe.

34 votes

Voici comment Facebook procède.

38voto

dungeon Hunter Points 2958

Nous avons utilisé l'approche suivante dans l'un de nos sites web de http://seclab.stanford.edu/websec/framebusting/framebust.pdf

<style>
 body { 
 display : none   
}
</style>
<script>
if(self == top) {
document.getElementsByTagName("body")[0].style.display = 'block';
}
else{
top.location = self.location;
}
</script>

4 votes

Bingo ! Je ne sais pas pourquoi cette réponse n'est pas plus votée car c'est la meilleure (après la réponse X-Frame-Options, mais c'est mieux de combiner les deux).

2 votes

Cette réponse ou la mienne devrait être sélectionnée :)

0 votes

J'aime votre idée d'utiliser à la fois cette réponse et la réponse X-Frame-Options:deny.

29voto

Jani Hartikainen Points 23183

J'ai trouvé ceci, et cela semble fonctionner au moins dans Firefox et le navigateur Opera.

if(top != self) {
 top.onbeforeunload = function() {};
 top.location.replace(self.location.href);
}

2 votes

Les solutions de Jani et de Jeff (une fois modifiées) sont toutes deux correctes et fonctionnent de manière équivalente ; Jani est accepté parce que sa solution fonctionne correctement sans aucune modification.

29 votes

Cela ne fonctionnera que si les deux fenêtres appartiennent au même domaine, ce qui est rare lorsque l'on veut s'échapper d'un cadre.

0 votes

S'il s'agit de cadres imbriqués, vous devrez parcourir la chaîne de cadres et supprimer tous les onbeforeunload et pas seulement celui qui se trouve en haut de l'échelle !

19voto

Josh Stodola Points 42410

Après y avoir réfléchi un moment, je pense que cela leur montrera qui est le patron...

if(top != self) {
  window.open(location.href, '_top');
}

Utilisation _top en tant que paramètre cible pour window.open() le lancera dans la même fenêtre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X