フレームバスターバスター…必要なバスターコード


422

他のサイトにあなたのサイトを「フレーム」にしたくないとしましょう<iframe>

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

したがって、すべてのページにアンチフレーミング、フレームバスティングJavaScriptを挿入します。

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

優秀な!これで、含まれているiframeから自動的に「バスト」または抜け出します。1つの小さな問題を除きます。

結局のところ次に示すよう、フレーム無効化コードが無効化される可能性があります

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

このコードは次のことを行います。

  • window.onbeforeunloadイベントハンドラーを介して、ブラウザーが現在のページから移動しようとするたびにカウンターをインクリメントします
  • を介してミリ秒ごとに起動するタイマーを設定し、setInterval()カウンターが増加していることを確認した場合、現在の場所を攻撃者が制御するサーバーに変更します
  • そのサーバーはHTTPステータスコード204のページを提供します。これにより、ブラウザーはどこにもナビゲートしません。

私の質問は-そしてこれは実際の問題よりもJavaScriptパズルの詳細です-どのようにしてフレームバストバスターを倒すことができますか?

私はいくつか考えましたが、私のテストでは何もうまくいきませんでした:

  • onbeforeunload介しonbeforeunload = nullてイベントをクリアしようとしても効果がなかった
  • alert()停止したプロセスを追加すると、それが発生していることがユーザーに通知されますが、コードに干渉することはありません。[OK]をクリックすると、バスティングが通常どおり続行されます
  • setInterval()タイマーをクリアする方法なんて考えられない

私はJavaScriptプログラマーではないので、ここで私の課題を説明します。バスター、フレームバストバスターをバストできますか?


6
私は確信してフレームバスターバスターが実際に動作いないよ...私は(私は204を返すように設定ハンドラにリダイレクト)それをテストしようとすると、それがナビゲートするから私を防ぎどこでもタイピングのものを含む-外部のページをアドレスバーに!どこにでもアクセスするには、ブラウザのタブを閉じて新しいタブを開く必要があります。したがって、言い換えれば、これが解決策を必要とするかどうかはわかりません。バスト解除したいフレームバスターバスターは...まずバストアップされるからです。:)(それか、私がテストを台無しにしたか、決して起こりえなかった...);)
Matt Winckler

16
上記のフレームバスターバスターのコードであるマットは間違いなく動作します。A ..ええと..私の友達..それについて私に..言った。か何か。:)
ジェフ・アトウッド

10
ジェフ、同じドメインの両方のウィンドウでテストしていますか?そうでない場合は、セキュリティ制限により 'onBeforeUnload'を変更できないためです
James

29
補足:例を投稿するときexample.orgは、RFC 2606 ietf.org/rfc/rfc2606.txt
Christoph

3
counter-counter-countermeasuresの一般的なテーマについて:galactanet.com/comic/view.php
Joey

回答:


149

これが実行可能かどうかはわかりませんが、フレームを壊すことができない場合は、警告を表示しないでください。たとえば、ページが「トップページ」でない場合は、フレームを分割しようとするsetIntervalメソッドを作成します。3または4回試してもページがトップページにならない場合は、ページ全体(モーダルボックス)を覆うdiv要素を作成し、次のようなメッセージとリンクを設定します。

不正なフレームウィンドウでこのページを表示しています-(何とか...潜在的なセキュリティ問題)

この問題を修正するには、このリンクをクリックしてください

最高とは言えませんが、彼らがそれから脱出する方法を彼らがどのように説明できるかはわかりません。


2
私はこれを試し、これでうまくいきました。このソリューションについて私が気に入っているもう1つの要素は、コンテンツにアクセスする前にユーザーがどのようなサイトにアクセスしていたかをユーザーに明らかにすることです。サンプルコード:if(parent.frames.length> 0){top.location.replace(document.location); setTimeout(function(){if(parent.frames.length> 0){document.location = " google.com ";}}、10); }
教皇、

これは悪用を回避するための良い方法であるだけでなく、サイトを覗き見するためだけにiframeを作成したいが、使用を許可しないサイトにとっては非常にフレンドリーです。理想的には、サイトのホームページのスクリーンショットを使用する必要があると思います。iframeで使用できない理由を上に重ねて説明します。
wheresrhys 2010

33
これがFacebookのやり方です。
shamittomar

2
しかし、バスティングサイトが偽のアンチアンチアンチを作成する場合、これは悪用される可能性があります...(現在のところ、どれほどのアンチダンノ)フィッシングリンクなどを表示するlighbox div ... tbc
yunzen

7
別のアイデアは、次のようなものでページを完全にdocument.write("");
消去

211

6
優れた、ブラウザでこれをサポートする.exeは間違いなく行く方法です。「ほとんどのブラウザー」と言うとき、具体的にはどのブラウザーですか?IE8以外の適切なソースが見つかりません。
ジェフ・アトウッド、

2
テストページは次のとおりです。enhanceie.com/ test / clickjack。Chrome 4.1.249.1042がサポートされています。Opera 10.50がサポートしています。Firefox 3.6.2はまだサポートしていません。Safari 4.0.3がサポートされています。
EricLaw

1
Firefox 3.6.9はそれをネイティブでサポートし(hackademix.net/2010/08/31/…)、NoScriptを使用するすべてのFirefoxインストールは2009年の初めからそれを持っています(hackademix.net/2009/01/29/x-frame- options-in-firefox
ssokolow 2010

4
これをJavaScriptフレームバスターと組み合わせるのが最適です。
ジェシーワイガート

1
または、このページの12月の12月の回答とこれを組み合わせてください:stackoverflow.com/a/13708510/328397
goodguys_activate

34

http://seclab.stanford.edu/websec/framebusting/framebust.pdfの Webサイトの1つで次のアプローチを使用しました

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

3
ビンゴ!これが最良の回答であるため、これ以上賛成されない理由がわかりません(X-Frame-Options回答の隣にありますが、両方を組み合わせるのが最善です)
Jesse Weigert

1
この回答または

これとX-Frame-Options:deny回答の両方を使用するという考えが気に入っています。
Max West

これにはJSが必要ですが、これはかなり大きな負担です。
Navin、2015

1
+1-これは、X-FRAME-OPTIONSを使用できない場合の最良の答えです。(たとえば、リファラーに応じて条件付きで許可または拒否する必要がある場合。)
Jay Sullivan

29

これに思いついた、そしてそれは少なくともFirefoxとOperaブラウザで動作するようです。

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

2
JaniとJeffの両方のソリューション(編集後)は正しく、同等に機能します。彼の解決策は編集なしで正しく機能したため、Janiに承認を与える
ジェフ・アトウッド

29
これは、2つのウィンドウが同じドメインにある場合にのみ機能します。フレームから脱出したいときにまれに発生します。
ジェームズ

ネストされたフレームが含まれている場合は、フレームチェーンを歩いて、上のonbeforeunloadハンドラーだけでなく、すべてのハンドラーを削除する必要があります。
クリストフ

12
重要な説明:iframe src =が動的に設定されていたため、クロスドメインポリシーが有効ではなかったため、これは私にとってはうまくいきました。JPは完全に正しいです。静的src =では、これは機能しません。
ジェフアトウッド

5
誰かがフレームバスターバスターバスターバスターを思いつくことができますか?
Epaga 2009年

23

サンドボックスをiframeに導入した現在のHTML5標準を考慮すると、攻撃者がサンドボックスを使用する場合、このページで提供されるすべてのフレーム無効化コードは、iframeが以下を制限するため無効にすることができます。

allow-forms: Allow form submissions.
allow-popups: Allow opening popup windows.
allow-pointer-lock: Allow access to pointer movement and pointer lock.
allow-same-origin: Allow access to DOM objects when the iframe loaded form same origin
allow-scripts: Allow executing scripts inside iframe
allow-top-navigation: Allow navigation to top level window

参照してください:http : //www.whatwg.org/specs/web-apps/current-work/multipage/the-if​​rame-element.html#attr-iframe-sandbox

次に、攻撃者が次のコードを使用してiframeでサイトをホストしていると考えてください。

<iframe src="URI" sandbox></iframe>

次に、すべてのJavaScriptフレーム無効化コードが失敗します。

すべてのフレームバスコードをチェックした後、この防御のみがすべてのケースで機能します。

<style id="antiClickjack">body{display:none !important;}</style>
<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

Gustav Rydstedt、Elie Bursztein、Dan Boneh、およびCollin Jacksonが最初に提案したもの(2010)


19

これをしばらく考えた後、これは上司が誰であるかを彼らに示すと信じています...

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

_topのターゲットパラメータとして使用window.open()すると、同じウィンドウで起動されます。


6
if (top != self) {
  top.location.replace(location);
  location.replace("about:blank"); // want me framed? no way!
}

6

私は勇敢になり、この帽子のリングに帽子を投げます(現状のままです)。収集できる反対投票の数を確認してください。

これが私の試みですが、テストしたすべての場所で機能するようです(Chrome20、IE8、FF14)。

(function() {
    if (top == self) {
        return;
    }

    setInterval(function() {
        top.location.replace(document.location);
        setTimeout(function() {
            var xhr = new XMLHttpRequest();
            xhr.open(
                'get',
                'http://mysite.tld/page-that-takes-a-while-to-load',
                false
            );
            xhr.send(null);
        }, 0);
    }, 1);
}());

このコードをに配置<head>し、の最後から呼び出して<body>、悪意のあるコードとの論争が始まる前にページがレンダリングされるようにします。これが最善の方法であるかどうかはわかりません。YMMV。

どのように機能しますか?

...私はあなたが尋ねるのを聞きます-まあ正直な答えは、私は本当にわかりませ。私がテストしているすべての場所で機能するようにするためには、多くのことを回避する必要がありました。実行する場所によって、実際の効果はわずかに異なります。

その背後にある考え方は次のとおりです。

  • 可能な限り短い間隔で実行するように関数を設定します。私が見た現実的なソリューションの背後にある基本的な概念は、フレームバスターバスターよりも多くのイベントでスケジューラーを埋めることです。
  • 関数が起動するたびに、上のフレームの位置を変更してみてください。かなり明白な要件。
  • また、完了するまでに長い時間がかかる関数をすぐに実行するようにスケジュールします(これにより、フレームバスターバスターが位置の変更を妨げないようにブロックします)。同期XMLHttpRequestを選択したのは、ユーザーの操作を必要としない(または少なくとも要求する)ことができ、ユーザーのCPU時間を消費しない唯一のメカニズムであるためです。

http://mysite.tld/page-that-takes-a-while-to-load(XHRのターゲット)には、次のようなPHPスクリプトを使用しました。

<?php sleep(5);

何が起こるのですか?

  • ChromeとFirefoxは、XHRが完了するまで5秒間待機してから、フレーム化されたページのURLに正常にリダイレクトします。
  • IEはほとんどすぐにリダイレクトします

ChromeとFirefoxでの待ち時間を回避できませんか?

どうやらそうではない。最初、XHRに404を返すURLを指定しました-これはFirefoxでは機能しませんでした。それから私がsleep(5);最終的にこの回答にたどり着いたアプローチを試し、それから私はさまざまな方法で睡眠時間をいじり始めました。動作に実際のパターンを見つけることはできませんでしたが、短すぎると、特にFirefoxがボールを再生しません(ChromeとIEはかなりうまく動作しているようです)。私が「短すぎる」の定義は実質であるかわからないが、5秒は思わたびに動作するように。


何が起こっているJavascript忍者が何が起こっているのかを少しよく説明したい場合、これが(おそらく)間違っている、信頼できない、彼らが今まで見た中で最悪のコードなどである理由を喜んで聞いてみます。


心配な文章はすべて削除できるようです
mplungjan

6

2015年の時点では、CSP2のframe-ancestorsディレクティブを使用する必要があります。これは、HTTP応答ヘッダーを介して実装されます。

例えば

Content-Security-Policy: frame-ancestors 'none'

もちろん、まだ多くのブラウザーがCSP2をサポートしていないため、古いX-Frame-Optionsヘッダーを含めることをお勧めします。

X-Frame-Options: DENY

とにかく両方を含めることをお勧めします。そうしないと、サイトは引き続き古いブラウザでのクリックジャッキング攻撃に対して脆弱であり、もちろん、悪意のある意図がなくても望ましくないフレーミングが発生します。最近、ほとんどのブラウザーは自動的に更新されますが、レガシーアプリケーションの互換性の理由から、企業ユーザーが古いバージョンのInternet Explorerに行き詰まる傾向があります。


1
すべての主要なブラウザーがCSPをサポートするようになりました。これは2019年の正解であり、予見できる未来です。
スティーブンR

5

わかりましたので、それはフレーム内にありました。そのため、GET変数としてパスを使用して、別の特別なページへのlocation.hrefを作成します。次に、何が起こっているのかをユーザーに説明し、target = "_ TOP"オプションのリンクを提供します。これはシンプルでおそらく機能するでしょう(まだテストしていません)が、ユーザーの操作が必要です。おそらく、問題のサイトをユーザーに指摘し、クリックジャッカーの恥のホールをどこかにあなたのサイトに作成することができます。


5

提案されたすべてのソリューションは、トップウィンドウの位置を直接強制的に変更します。ユーザーがフレームをそこに置きたい場合はどうなりますか?たとえば、検索エンジンの画像結果の一番上のフレーム。

私は、デフォルトですべての入力(リンク、フォーム、および入力要素)が無効になっているか、アクティブにされても何もしないプロトタイプを書きました。

包含フレームが検出された場合、入力は無効のままにされ、警告メッセージがページの上部に表示されます。警告メッセージには、安全なバージョンのページを新しいウィンドウで開くリンクが含まれています。これにより、ページがクリックジャッキングに使用されるのを防ぎ、他の状況でもユーザーがコンテンツを表示できるようにします。

含まれるフレームが検出されない場合、入力が有効になります。

これがコードです。標準のHTML属性を安全な値に設定し、実際の値を含む追加の属性を追加する必要があります。それはおそらく不完全であり、完全な安全のために追加の属性(私はイベントハンドラについて考えています)はおそらく同じ方法で処理する必要があります。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
  <head>
    <title></title>
    <script><!--
      function replaceAttributeValuesWithActualOnes( array, attributeName, actualValueAttributeName, additionalProcessor ) {
        for ( var elementIndex = 0; elementIndex < array.length; elementIndex += 1 ) {
          var element = array[ elementIndex ];
          var actualValue = element.getAttribute( actualValueAttributeName );
          if ( actualValue != null ) {
            element[ attributeName ] = actualValue;
          }

          if ( additionalProcessor != null ) {
            additionalProcessor( element );
          }
        }
      }

      function detectFraming() {
        if ( top != self ) {
          document.getElementById( "framingWarning" ).style.display = "block";
        } else {
          replaceAttributeValuesWithActualOnes( document.links, "href", "acme:href" );

          replaceAttributeValuesWithActualOnes( document.forms, "action", "acme:action", function ( form ) {
            replaceAttributeValuesWithActualOnes( form.elements, "disabled", "acme:disabled" );
          });
        }
      }
      // -->
    </script>
  </head>
  <body onload="detectFraming()">
    <div id="framingWarning" style="display: none; border-style: solid; border-width: 4px; border-color: #F00; padding: 6px; background-color: #FFF; color: #F00;">
      <div>
        <b>SECURITY WARNING</b>: Acme App is displayed inside another page.
        To make sure your data is safe this page has been disabled.<br>
        <a href="framing-detection.html" target="_blank" style="color: #090">Continue working safely in a new tab/window</a>
      </div>
    </div>
    <p>
      Content. <a href="#" acme:href="javascript:window.alert( 'Action performed' );">Do something</a>
    </p>
    <form name="acmeForm" action="#" acme:action="real-action.html">
      <p>Name: <input type="text" name="name" value="" disabled="disabled" acme:disabled=""></p>
      <p><input type="submit" name="save" value="Save" disabled="disabled" acme:disabled=""></p>
    </form>
  </body>
</html>

これに関する問題は、フレームメーカーがposition:absoluteを使用してアクティブなボタンを非アクティブなボタンの上に配置することであり、ユーザーはWebページを見て、自分のボタンをクリックしていると考えるだけです。
jmucchiello 2009年

警告メッセージは引き続き表示されますが、もちろん、安全なページへのリンクを簡単にカバーできます。しかし、単純にページをコピーして同じ効果を得ることができるのに、なじみのあるボタンをクリックするように私のページをフレーミングするすべての問題を経験するのはなぜですか?上記のコードは主にクリックジャッキングを防ぎます。別のページの上に私のページを見えないように表示すると、私のサイトでアクションを呼び出すことができません。
ヨハン・スタイツ2009年

これがIE8制限付きゾーンフレームまたはChromeサンドボックスフレームに配置されている場合、JavaScriptは実行されません。それらの場合にどのような変更が必要かと思います
goodguys_activate '28年

4

まあ、あなたはカウンターの値を変更することができますが、それは明らかに壊れやすい解決策です。サイトがフレーム内にないことを確認した後、AJAXを介してコンテンツをロードできます。これも優れたソリューションではありませんが、on beforeunloadイベントの起動を回避できると期待しています(私は想定しています)。

編集:別のアイデア。フレーム内にいることを検出した場合は、目的のURLに移動するリンクをクリックする前に、ユーザーにJavaScriptを無効にするように依頼します(ページに通知するクエリ文字列を渡して、ユーザーがJavaScriptを再度有効にできることをユーザーに通知しますある)。

編集2:核に入る-フレーム内にいることがわかった場合は、ドキュメントの本文のコンテンツを削除し、厄介なメッセージを出力します。

編集3:最上位のドキュメントを列挙して、すべての関数をnullに設定できますか(匿名関数も含む)?


それがフレームから抜け出すことができない場合、Outlook(旧Hotmailの)「原子力行く」 -それは、全体の内容を置く<body>の内側<plaintext>にタグセットdisplay: none。それは非常に効果的です。
uınbɐɥs

4

バスターコードの直後にアラートを追加すると、アラートによってJavaScriptスレッドが停止し、ページが読み込まれます。これはStackOverflowが行うことであり、フレームバスティングバスターを使用しても、iframeからバストアウトします。また、私の簡単なテストページでも機能しました。これは、Windows上のFirefox 3.5およびIE7でのみテストされています。

コード:

<script type="text/javascript">
if (top != self){
  top.location.replace(self.location.href);
  alert("for security reasons bla bla bla");
}
</script>

3

あなたはほとんどそこにいたと思います。やってみました:

window.parent.onbeforeunload = null;
window.parent.location.replace(self.location.href);

または、代わりに:

window.parent.prevent_bust = 0;

注:実際にはテストしていません。


1
コードサンプルを編集しました(親のテストは失敗したようです)が、編集したバージョンは機能しているようです。
Jeff Atwood、

1
涼しい。テストされていないコードで答えるのは常にトリッキーです-私は少なくともアイデアを理解させるためにそれを行い、貧しいアスカーにデバッグさせます。:)
ジェフ・ミートボール・ヤン

12
親が別のドメインにいる場合は機能しません。
Josh Stodola、

2

バスターを繰り返し呼び出すことについてはどうですか?これにより競合状態が発生しますが、バスターが上に出てくることを期待できます。

(function() {
    if(top !== self) {
        top.location.href = self.location.href;
        setTimeout(arguments.callee, 0);
    }
})();

2

setInterval()それらによって返される値を見ると、通常は1桁なので、通常は1行のコードでそのような割り込みをすべて無効にできます。

for (var j = 0 ; j < 256 ; ++j) clearInterval(j)

2

私はちょうどフレームバスターバスターJavaScriptをバストする方法を手に入れたばかりかもしれません。JavaScript関数でgetElementsByNameを使用して、フレームバスターと実際のフレームバスターバスタースクリプトの間にループを設定しました。この投稿をチェックしてください。http://www.phcityonweb.com/frame-buster-buster-buster-2426


0

setIntervalおよびsetTimeoutは、自動的に増分する間隔を作成します。setTimeoutまたはsetIntervalが呼び出されるたびに、この数は1つずつ増えるため、setTimeoutを呼び出すと、現在の最高値が取得されます。

   var currentInterval = 10000;
   currentInterval += setTimeout( gotoHREF, 100 );
   for( var i = 0; i < currentInterval; i++ ) top.clearInterval( i );
   // Include setTimeout to avoid recursive functions.
   for( i = 0; i < currentInterval; i++ )     top.clearTimeout( i );

   function gotoHREF(){
           top.location.href = "http://your.url.here";
   }

10000のsetIntervalsとsetTimeoutsが同時に機能することはほとんど前例がなく、setTimeoutは「最後の間隔または作成されたタイムアウト+ 1」を返すため、top.clearIntervalは引き続きアクセスできるため、これはフレームへのブラックハット攻撃を無効にします。上記のウェブサイト。


0

htaccessを使用して、ハイジャックするフレームセット、iframe、および画像などのコンテンツを回避します。

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://www\.yoursite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule ^(.*)$ /copyrights.html [L]

これは期待されたものの代わりに著作権ページを表示します。


これは、a)常に設定されているわけではない(ブラウザーの設定や拡張機能のため、または単に参照ページがHTTPSを使用<meta name="referrer" …/>していないために使用されていないため、b)リンクをクリックしたときにも設定されているため、ページへのリンクを許可せず、中断するウェブ。
マーティン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.