435

他のサイトがあなたのサイトを「フレーム化」したくないとしましょう<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 プログラマーではないので、ここであなたに挑戦します。ねえ、バスター、フレームバスター バスターをバストできますか?

4

20 に答える 20

150

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

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

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

最高ではありませんが、彼らがそれから抜け出す方法をスクリプト化できる方法はわかりません。

于 2009-06-18T13:21:16.620 に答える
39

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>
于 2012-12-04T17:26:26.810 に答える
30

これを思いついたのですが、少なくとも Firefox と Opera ブラウザーでは動作するようです。

if(top != self) {
 top.onbeforeunload = function() {};
 top.location.replace(self.location.href);
}
于 2009-06-06T04:55:18.953 に答える
19

しばらく考えてみたところ、上司が誰なのかがわかると思います...

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

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

于 2009-06-18T14:40:02.810 に答える
9

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

例えば

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

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

X-Frame-Options: DENY

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

于 2015-07-08T09:01:01.293 に答える
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 で待ち時間を回避できない?

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


通りすがりの Javascript 忍者が、何が起こっているのか、なぜこれが (おそらく) 間違っているのか、信頼性が低いのか、彼らが今まで見た中で最悪のコードなのかなどをもう少し詳しく説明したい場合は、喜んで耳を傾けます。

于 2012-08-15T15:38:21.250 に答える
6
if (top != self) {
  top.location.replace(location);
  location.replace("about:blank"); // want me framed? no way!
}
于 2009-06-19T15:23:24.917 に答える
6

提案されたすべての解決策は、上部ウィンドウの位置を直接強制的に変更します。ユーザーがフレームを表示したい場合はどうすればよいでしょうか? たとえば、検索エンジンの画像結果のトップ フレーム。

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

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

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

これがコードです。標準の 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>
于 2009-06-19T01:47:38.370 に答える
5

わかりましたので、フレーム内にあることがわかりました。そのため、パスを GET 変数として別の特別なページに location.href します。ここで、何が起こっているかをユーザーに説明し、target="_TOP" オプションを含むリンクを提供します。これは単純で、おそらく機能します (テストしていません) が、ユーザーの操作が必要です。問題のあるサイトをユーザーに指摘して、どこかのサイトにクリックジャッカーの恥の殿堂を作ることができるかもしれません.. ただのアイデアですが、それは夜の仕事です..

于 2009-06-12T01:44:09.500 に答える
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>
于 2009-07-22T09:17:09.400 に答える
4

カウンターの値を変更することはできますが、それは明らかに脆弱な解決策です。サイトがフレーム内にないと判断した後、AJAX を介してコンテンツを読み込むことができます。これも優れた解決策ではありませんが、on beforeunload イベントの発生を回避できることを願っています (私は想定しています)。

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

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

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

于 2009-06-06T04:40:24.230 に答える
3

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

for (var j = 0 ; j < 256 ; ++j) clearInterval(j)
于 2010-02-21T08:57:59.750 に答える
3

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

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

または、代わりに:

window.parent.prevent_bust = 0;

注: 私は実際にこれをテストしませんでした。

于 2009-06-06T04:48:32.083 に答える
2

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

于 2011-02-20T14:42:48.533 に答える
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 は引き続きアクセス可能であるため、フレームへのブラックハット攻撃を打ち負かします。上記で説明されている Web サイト。

于 2009-12-23T15:40:15.697 に答える
0

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

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

これにより、予想されるのではなく、著作権ページが表示されます。

于 2013-12-18T19:14:53.450 に答える
0

postMessage()この方法を使用して、一部のドメインにコンテンツへのアクセスと表示を許可し、他のすべてのドメインをブロックすることで、アイデア全体を改善できます. 最初に、コンテナの親は、ページを表示しようとしているcontentWindowの にメッセージを投稿して自己紹介する必要があります。iframeそしてあなたのページはメッセージを受け入れる準備ができていなければなりません。

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
  // Use event.origin here like
  if(event.origin == "https://perhapsyoucantrustthisdomain.com"){
  // code here to block/unblock access ... a method like the one in user1646111's post can be good.
  }
  else{
  // code here to block/unblock access ... a method like the one in user1646111's post can be good.
  }
}

load最後に、イベントを待機する関数内に物をラップすることを忘れないでください。

于 2020-08-25T11:22:40.437 に答える