問題描述

一些網站有 IFRAME 機櫃的”break out” 的程式碼,這意味著如果一個頁面 A 作為 IFRAME 載入到父頁面 P 中,A 中的一些 Javascript 將外部視窗重定向到 A

通常這個 Javascript 看起來像這樣:

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

我的問題是:作為父母頁面 P 而不是 A 內頁的作者,如何防止 A 做這個 break-out?

附:在我看來,它應該是一個 cross-site 安全違規,但它不是。

最佳解決方案

嘗試使用 onbeforeunload 屬性,這將允許使用者選擇是否要離開頁面。

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

在 HTML5 中,您可以使用沙盒屬性。請參見下面 Pankrat 的答案。 http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

次佳解決方案

使用 HTML5 新增了 iframe sandbox 屬性。在寫這篇 works on Chrome, Safari, Firefox and recent versions of IE and Opera 的時候,幾乎要做的就是:

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

如果要允許 top-level 重定向指定 sandbox="allow-top-navigation"

第三種解決方案

我用 sandbox = “…”

  • allow-forms 允許表單提交

  • allow-popups 允許彈出視窗

  • allow-pointer-lock 允許指標鎖定

  • allow-same-origin 允許檔案保持其起源

  • allow-scripts 允許 JavaScript 執行,並且還允許功能自動觸發

  • allow-top-navigation 允許檔案透過瀏覽 top-level 視窗來突破框架

頂部導航是您想要防止的,所以請留下,不會被允許。任何遺漏的東西都將被阻止

恩。

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>

第四種方案

閱讀 w3.org spec 後。我找到了沙盒屬性。

您可以設定 sandbox="",阻止 iframe 重定向。話雖如此,它也不會重定向 iframe 。您將基本失去點選。

示例:http://jsfiddle.net/ppkzS/1/沒有沙箱的例項:http://jsfiddle.net/ppkzS/

第五種方案

我知道問題已經很久了,但是這裡是我的改進版本,只有當 iframe 載入時,它才會等待 500ms 的任何後續呼叫。

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

onload="frameLoad()"onreadystatechange="frameLoad();"必須新增到框架或 iframe 。

第六種方案

我發現了一些有用的駭客:

Using JS how can I stop child Iframes from redirecting or at least prompt users about the redirect

http://www.codinghorror.com/blog/2009/06/we-done-been-framed.html

http://coderrr.wordpress.com/2009/02/13/preventing-frame-busting-and-click-jacking-ui-redressing/

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇