Thursday, April 5, 2007

Working on eval solution ...

Sorry guys, I'm trying to solve the problem but it seems really hard to do.

I found a new way but I tested this piece of code:

Function.prototype.constructor = function(){
sendToMaliciousCode.apply(null, arguments);
return function(){};
};


and I noticed that it changes even (function(){}).constructor ... that's why constructor is not read only and it can't be deleted.

I hope I'll find a solution as soon as I can ... and please sorry for fakes solutions.



Update
I don't know if this piece of code should be useful or should resolve the problem ... I'm testing them but I can't crack them.

function safeEval(c){
var f = function(){},
m = "constructor";
if(new f[m]() instanceof f[m])
return new f[m]("", "return "+c)()
};

alert(
(function(c,f,m,u){f=function(){},m="constructor";return new f[m]() instanceof f[m]?new f[m]("","return "+c)():u})
("[1,2,3]")
);

This is a bit bigger than old version but seems to be safer because any prototype, constructor change or re-defined Function seems to be able to recieve data (in this case a simple "[1,2,3]" string).
Please tell me if You find a way to crack this solution, thank You!


Update - Damn, I had It under my nose but I didn't see them!!!
Trick showed above seems to be good but too much "strange" and uses too much bytes!
Here there's another version, based, this time, on typeof statement.

var safeEval = function(c){
var f = Function;
if(typeof new f() === "function")
return new f("","return "+c)();
};

alert(
(function(c,f,u){f=Function;return typeof new f()==="function"?new f("","return "+c)():u})
("[1,2,3]")
);


Why typeof statement?
JavaScript constructors are functions and every kind of constructor returns a typeof object.
Every instances require to use new and this is another keyword that You can't change!

What is the only constructor that returns a function and not an object?
The Function itself!!!


alert(typeof new WhatEverYouWant); // object

alert(typeof new Function); // function

It seems to be a valid solution for IE, FireFox and Opera, I need debug with Safari and other browsers, please tell me if You find a way to crack this other code, thank You again!


Update for XMLHttpRequest check
if((function(x,m,c,f,t){f=Function;if(typeof new f()===c){t=x[m];delete x[m];if(typeof new f("","return "+x)()!==c){x[m]=t;return 1}}})(XMLHttpRequest,"toString","function"))
alert("XMLHttpRequest is OK");
else
alert("XMLHttpRequest is Corrupted");

If typeof solution is not crackable, this one is safe too to know if original XMLHttpRequest object has been cracked.
Thank You again for debug and tests


Update - I forget last Array & Object security check
if((function(m){function $(c,t,f){f=Function;if(typeof new f()==="function"){t=c[m];delete c[m];try{new f("",c)}catch(e){c[m]=t;return 1}}};return $(Array)&&$(Object)})("toString"))
alert("I can decode a JSON string");
else
alert("JSON decoding is corrupted");


And this is my last proposal
json = "[1,2,3]";

result=(function(c,m,f){m="toString";f=Function;function $(c,t){if(typeof new f()==="function"){t=c[m];delete c[m];try{new f("",c)}catch(e){c[m]=t;return 1}}};if($(Array)&&$(Object))return new f("","return "+c)()})
(json);

alert(result);


This is an inline function that should solve Array and Object modified constructors problem returning a safe decoded json string.

It's about 220 bytes and this is the best security inline JSON decoding I thought, I hope this will be useful, not to solve JavaScript security problems but, at least, to solve eval, Array and Object paranoia.

Regards :)



Update - I cracked my solution

Function = (function(Functiold, Arrold, Objold){
function setArrayObject(){
Array = function(){
return new Arrold;
};
Array.toString = function(){
return ""+Arrold
};
Object = function(){
return new Objold;
};
Object.toString = function(){
return ""+Objold
};
f.toString = function(){
return ""+Functiold
};
};
var f = function(){
var a = arguments;
Functiold.prototype.constructor = Function;
Functiold.prototype.name = "anonymous";
setArrayObject();
delete Array.toString;
delete Object.toString;
if("" + a[1] === "" + Array)
a[1] = Arrold;
else if("" + a[1] === "" + Object)
a[1] = Objold;
setArrayObject();
return Functiold(a[0], a[1]);
};
setArrayObject();
return f;
})(Function, Array, Object);


It seems that first way is my last choice, using instanceof ... but probably I'll crack them too ... please stay tuned
This trick cracks first solution too.
At this point I'm going to do something else because it seems that there's no way with Internet Explorer, Opera and other browsers, to do a safe code evaluation.

With FireFox, You can delete eval and after that, use eval.
Bye

No comments:

Post a Comment