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 :
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.
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.
also tried following :
var greaseObject =new unsafeWindow.namespace.constructor();
again greaseObject remains undefined.
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 ?
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 ofunsafeWindow
. Any code executed in the scope of thiswindow
object will behave if it was a part of the actual page, similarly to the Content Scripts at Google Chrome's extensions.Code
Security considerations
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.$_WINDOW
Examples / Proof of Concept
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
.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;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. WhenunsafeWindow
is used, thearguments.callee.caller
variable cannot be called. The function will then be displayed asfunction SJOWContentBoundary{ [native code]}
. However, when$_WINDOW
is used, the real GM function is visible and callable by the remote page.Example 1: Reading (sensible) data from a GreaseMonkey script
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.
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.