Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global Eval with return value ?

After searching a while , I was hoping to find a solution for global eval with a return value.

  • eval will run in the current scope
  • Function constructor will execute in its own local scope with access to global scope
  • setTimeout trick is an async operation
  • script injection can not return value
  • window.execScript also - can not return value

So my question is:

Is there any other technique which runs at the global scope and can return value ?

(example will be much appreciated).

like image 315
Royi Namir Avatar asked Oct 02 '22 14:10

Royi Namir


1 Answers

You can make eval to run in global scope, instead of

eval(s)

just use

window.eval(s);

or

var e=eval; e(s);

or

[eval][0](s)

This surprisingly happens because Javascript is weird and has a special rule about eval: when you're using the original eval object directly to evaluate a string the evaluation happens in the current context.

If an "indirect eval" is used instead (i.e. you store eval in a variable and then use the variable, or even if you access eval using the window object) the evaluation happens in the global context.

You can check this in a Javascript console:

function foo() {
    eval("function square(x){ return x*x; }");
}

function bar() {
    window.eval("function square(x){ return x*x; }");
}

foo()

square(12) // <-- this gives an error; direct evaluation was used

bar()

square(12) // <-- this returns 144

So window.eval(s) is not the same as eval(s) even if window.eval === eval.

PS

Note that eval has a special specific language rule for this to happen, but the same apparently strange behavior can also be observed in other cases for a different reason.

If you have an object x with a method defined m then

x.m()

is not the same as

var mm = x.m; mm();

because this in the first case will be bound to x during execution of the code in m while in the second case this will be the global object.

So also in this case x.m() is different from mm() even if x.m === mm.

For the same reason x.m() is not the same as [x.m][0]() because in the latter this will be bound to an array object during the execution of method code instead of being bound to x.

like image 151
6502 Avatar answered Oct 11 '22 14:10

6502