My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Friday, April 13, 2007

JavaScript private Python style properties - yet another experiment

JavaScript constructors (call them classses if You prefere) have some problem with private parameters or private methods.

To use a private parameter You should simply use a variable without this as scope prefix
function MyConstructor(){
this.getPrivate = function(){
return private;
};
var private = "something";
};

It's simple and it works perfectly.
Any external scope could get directly private variable and You can know its value only calling getPrivate method.

var obj = new MyConstructor;
alert(obj.getPrivate());

The cool thing is that if You change externally returned value it will not be changed inside object too but please remember that if You change them and it's a generic object or an array, these changes will be valid inside object scope too (object and arrays are sent by reference, You need to clone or copy them before to return them externally).

Well, this is just a private parameters introduction and this is not useful if You write only using prototype or Class.create style, everything, in these cases, will be public (remember that).

The other "trick" to have a private method is to use internal scope (nested) constructor functions.
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
this.public = what;
setPrivateValue(what + private);
};

function setPrivateValue(what){
private = what;
};

var private = "something";
};

Well done, we have a public method and a private one ... but what should we do to have correct scope inside private methods too?
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
setValue("no " + what);
};

function setValue(what){
this.public = what;
};
};

Above code will not work because when You call a function without a dedicated scope, using for example apply or call, this will be just the global window object (super object).
We need to use call or apply, and problem is solved
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
setValue.call(this, "yes " + what);
};

function setValue(what){
this.public = what;
};
};
var o = new MyConstructor;
alert(o.public);
o.setPublicValue("now I can set them");
alert(o.public);



Well ... and what about choosed topic?
These examples shows that JavaScript constructors should have both private parameters and methods, but sometimes I think about other languages style and this is my experiment.
function MyConstructor(a,b,c){

this.getVar = function(){
return this.__privateVar;
};

this.setVar = function(){
this.__privateMethod("private var setted by a private method");
};

this.__privateVar = "private var";

this.__privateMethod = function(arg){
this.__privateVar = [arg, [a,b,c]].join("\n");
};
};

MyConstructor = MyConstructor.toPrivate();

var asd = new MyConstructor(1, {}, false);
alert(asd.__privateVar); // undefined !!!
alert(asd.getVar()); // private var
asd.setVar();
alert(asd.getVar());
// private var setted by a private method
// 1, [object Object], false

"Public" parameters and methods that use double underscore "__" as prefix are privates!
This means that You can just write without apply or call problems simply calling private variables or functions using this as scope prefix and "__" before real name.
You could even call two vars or methods in the same way, just add __ before private one.


How can we do it?
Using this stupid prototype:
Function.prototype.toPrivate = function(){
var c = "".concat(this),
o = new this,
v = [],
k;
for(k in o) {
if(k.substr(0,2) === "__") {
v.push("var ".concat(k, "=o.", k, ";"));
c = c.replace(new RegExp("\\bthis\\s*\\.\\s*(".concat(k, ")\\b"), "g"), "$1");
if(o[k] && o[k].constructor === Function)
c = c.replace(/\}\s*$/, k.concat("=(function(s,m){return function(){return m.apply(s,arguments)}})(this,", k, ");", "}"));
}
};
eval(v.join("").concat("c=", c));
c.prototype = this.prototype;
return c;
};

Seems horrible? Yes, it is :D

What about this proto limits?
Well, the first limit is that I suggest You to write private methods or parameters correctly, as I showed at the top of this post, because a code that use eval and works on constructor toString native or modified method isn't a cool way to solve private scope.
The second limit is that You need to remember to call toPrivate prototype.
There are probably other limits but as I wrote, this is just an experiment, I hope funny for your "JS dynamic investigation", bye :)

JSON and JSONRequest

I've just updated last JSON JavaScript object adding a dependency on JSONError dedicated error object.

I've uploaded a new object too, called JSONRequest and based on Douglas Crockford proposal.

I successful tested both JSON and JSONRequest but last one probably need more debug to work perfectly.

JSONRequest object allows developer to do more than a single JSON interaction using a queue variable to block multiple request errors and to reduce server requests, performing each request only if precedent one is completed.

The usage is very simple and if You read "official" JSONRequest page You'll agree that everything was implemented, except for server specs.

Server side should check Content-Type, with this object always setted as application/jsonrequest.
For POST requests server side will recieve a JSONRequest key that will contain JSON Array or Object rappresentation encoded using encodeURIComponent.

Compatibility should be good enought, starting with IE 5.5 and if You have a personal encodeURIComponent top level function should run with IE5 too.

Opera, as FireFox and Safari should work correctly.
I'm waiting for your opinion about this object, I'm just using them but I'm not yet totally sure this respect perfectly Douglas Crockford idea so please tell me what's wrong or what doesn't work as expected, thank You :)

Where is the link? It's here ;)

Instant Update
I uploaded a packer version of these 4 objects too, about 4.6 Kb

Thursday, April 05, 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

My last JSON parser? Out!

I've just uploaded my last JSON object in devpro, merging last tips & tricks to make JSON encoding and decoding faster and a bit safer.

These are my JSON object features:

  1. fast, it encodes very quickly every JSON compatible JavaScript variable

  2. library unobtrusive, its methods can be used both directly or prototyped

  3. safe, it ignores constructor cracked variables and uses a "secure" evaluation

Third point doesn't mean that this object can prevent XSS or Ajax JavaScript Hijacking problems but if You write secure applications You should believe in its features to prevent malicious code.
For example, if You reload this object each interaction during a server response You'll be more secure during Array or Object convertion using code evaluation but please read Ajax security problems to know more.

You can find this object here while You can read documentation page (thanks to Natural Doc) using this link.

Wednesday, April 04, 2007

I'll probably never understand Internet Explorer

I was coding to solve eval re-definition problem ... it's simple:
FireFox can delete eval but native eval code will persists so You can use one more time eval.

IE7 can delete eval ... and after this operation, eval will be not usable ...

What's the awesome behaviour?
IE7 has another method to evaluate code, execScript ... and It doesn't accept this code
execScript = function(){};

Cool? It seems that I can believe on execScript and delte eval only on FireFox ... why not?

Because IE7 accepts this code
window.execScript = function(){};


So bye bye execScript, You've been defined ... but the coolest thing is that after that code, You can't do:
delete window.execScript;


It's amazing IE7 deveolpers, thank you one more time!

Tuesday, April 03, 2007

Are 130 byte enought to solve JavaScript JSON Hijacking problems? (Unlikely not this time)

This is the second time I open this post because I didn't do a good debug but my solution, a sort of personal brainstorming, was good enough to open one more time this post after few changes :)

This is my proposal:

(function(m){function $(c,t){t=c[m];delete c[m];try{eval(""+c)}catch(e){c[m]=t;return 1}};return $(Array)&&$(Object)})("toString")

exactly 130 byte to solve (I suppose) Array and Object modified constructor problems.



(function(m){function $(c,t){t=c[m];delete c[m];try{new(function(){}).constructor("",""+c)}catch(e){c[m]=t;return 1}};return $(Array)&&$(Object)})("toString")

exactly 158 byte to solve (I suppose) Array and Object modified constructor problems.

Let me explain this function concept.

Step 1 - There's no way to know if a constructor is native
This is the first problem, we can't believe on a generic object constructor for, at least, these two reason:

  1. a constructor, as I wrote on MDC too, is not read only

  2. there isn't any official method to know if a part of code is native or not, and if it is implemented, it should be changed by malicious arbitrary code


Since a constructor should be redefined in some browser (first of all, FireFox)
function Array(){ /*doStuff*/ };

is really hard to know if this new constructor is native code or not.
You could create a new original, empty, scope (using for example an iframe), then You can check if a variable constructor, in this new scope, is equal to original one, for example, a generic Array in a generic window.
The only way to know if a constructor was inherited from JavaScript core is its string rappresentation, usually something like:

function Array() {
[native code]
}

This is a common native code string rappresentation, but as You know JavaScript is object oriented and every object has a native toString method that should be override/overwite as every other public method.

function Array(){};
Array.toString = function(){
return "function Array(){\n\t[native code]\n}"
};

alert(Array);

This means that we can't believe on string rappresentation too ... and that's why I thought about next step.



Step 2 - native code cannot be evaluated
The uniq way to know if a method or a constructor is inherited from JavaScript core is the "[native code]" string inside its string value.
At the same time You can't evaluate a native code because it isn't a replicable JavaScript code, so a try...catch like this one should be a trick to know if code is native or not because in this last case it will not make code executable:

function isNativeCode(methodOrConstructor){
var result = false;
try{eval(""+methodOrConstructor)}
catch(e){result = true};
return result;
};

alert([
isNativeCode(Array), // true
isNativeCode(String.replace), // true
isNativeCode((1).constructor), // true
isNativeCode(function(){}) // false
]);

As I said, overwriting toString method should produce a sort of native code simply and quickly:

function Mine(){};
Mine.toString = function(){
return "[native code]"
};

alert(isNativeCode(Mine)); // true

This is the reason I thought about next final step.


Step 3 - enumerable methods should be deleted!
At this point, the biggest problem is the ability to reply native code string, using for example a toString method.
Is it possible to solve? Likely sure, using a delete keyword!

function Array(){};
Array.toString = function(){
return "I'm an Array";
};

alert(Array); // I'm an Array

delete Array.toString;

alert(Array); // function Array(){\n}

Amazing, I can remove arbitrary toString method to know original value ... but does delete work without problems with native constructor too? Of course, it's on core ;)

alert(Array.toString());
// function Array(){\n\t[native code]\n}

delete Array.toString;

alert(Array.toString());
// function Array(){\n\t[native code]\n}

Well done ... but this should be quite obtrusive because some library (or some developer) should redefine toString method for its scope ... that's why I decieded to assign one more time toString method, after deleting them, obviously ... and this is my first proposal, with details:

// anonymous private scope function, accept one argument
(function(m){

// private useful dollar function
// accepts 2 arguments, one for constructor
// and one for lazy programming
function $(c,t){

// second argument is used to save old toString method
t=c[m];

// delete removes constructor toString
delete c[m];

// check if constructor contains native code
// (not usable, not evaluable)
try{eval(""+c)}

// if eval fails, constructor contains
// [native code]
catch(e){

// so I can add safely old toString method
// (is not a problem if it is native or not)
c[m]=t;

// and return a "true" value
return 1
}
};

// at this point I just need to call
// my dollar function to know
// if Array and Object are native constructors
return $(Array)&&$(Object)
})
// for size reasons, I send toString method name
// using "m" var multiple times inside function
("toString")


How to use this runtime private scope function?
This is just an example that should be used before every JSONString to value convertion:

if((function(m){function $(c,t){t=c[m];delete c[m];try{eval(""+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 that's all folks, You can view a basic example in this page and a failed hack example in this one.

Finally, this inline function should work with every Ajax ready browser, successfully tested on IE 5, 5.5, 6, 7, FireFox 1, 1.5, 2 and Opera 8, 9.

I'm waiting for Safari 1 or 2 behaviour, as konqueror or other browsers (but I'm quite sure, this time this proposal should work correctly).

If You find a way to crack this solution, please tell me (us) :D


Update - 04/04/2007
This is a revisited version dedicated for XMLHttpRequest native object

if((function(c,m,t){t=c[m];delete c[m];if(/^\[XMLHttpRequest\]$/.test(c)){c[m]=t;return 1}})(XMLHttpRequest,"toString"))
alert("Valid XMLHttpRequest");
else
alert("XMLHttpRequest is corrupted");


Same concept, same logic ... and should be as secure as first proposal for Array and Object constructors.

Try them:

function XMLHttpRequest(){};
XMLHttpRequest.toString = function(){
return "[XMLHttpRequest]"
};
XMLHttpRequest.constructor = Object;

if((function(c,m,t){t=c[m];delete c[m];if(/^\[XMLHttpRequest\]$/.test(c)){c[m]=t;return 1}})(XMLHttpRequest,"toString"))
alert("Valid XMLHttpRequest");
else
alert("XMLHttpRequest is corrupted");



Update - 04/04/2007
Do You worry about eval?

if(eval === (new function(){}).eval)
alert("OK eval");
else
alert("eval is corrupted");

And now we just need to pray that deprecated object.eval will survive for some year :D



Instant Update - 04/04/2007
damn ... Object.prototype.eval should redefine generic object eval method ... uhm, please let me think about a solution and sorry for precedent update.


Update - 05/04/2007
kentaromiura gives me a nice idea ... He wrote them next post.
Function can eval() code in a safe way.
You can redefine Function itself but in this case native behaviour will be lost so I suppose this should be the better way to be sure that code evaluation and Array/Object constructors are not modified.

var result, code = '[1,2,3]';
if((function(m){function $(c,t){t=c[m];delete c[m];try{new Function("",c)}catch(e){c[m]=t;return 1}};return $(Array)&&$(Object)})("toString"))
result = new Function("","return "+code)();

Is this the securest way, for JavaScript, to know if code has been cracked?


Instant Update
no man ...
function Function(a,b){
// Array = function(){} ...
eval("function f(){"+b+"}");
return f;
};

alert(new Function("","return [1,2,3]")());

:(


Important Update - 05/04/2007
I found a way to solve eval problems, look here to know more.
This is the last version, it should be the best way to know if Array and / or Object were cracked.

/*
function Array(){};
Array.toString = function(){
return "function Array(){\n\t[native code]\n}"
};
//*/

if(
(function(m){function $(c,t){t=c[m];delete c[m];try{new(function(){}).constructor("",""+c)}catch(e){c[m]=t;return 1}};return $(Array)&&$(Object)})("toString")
)
alert("Array and Object constructors are OK");
else
alert("Corrupted Array and Object constructor");


With this concept I should be shure that XMLHttpRequest object is native and not re-defined.

Here You can read my last proposal for XMLHttpRequest check:

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


It seems to be safe as function(){} code evaluation is.
If XMLHttpRequest is not native, it's a function and removing, using delete, its toString method, it should be a constructor and a constructor has a function(){} constructor, isn't right?

Semantic Import

With MetaDOM style I wrote a little function to add runtime external scripts, this time compatible with all modern browser ;)

This function is similar with Python import syntax, using From to specify a folder, or why not an uri, Import to add one or more script and finally an optional And method to call a callback on scripts loaded.

Here You can view an example
From("jsFolder") . Import("MyScript", "MyOhterScript")


Seems cool?
The first goal is to add dynamically one or more script in a simple and fast way.
These script will be available on onload event if they're imported before this event.
These scripts should be available on DOMContentLoaded too, but to be sure these script will be available You could add a callback using last method.

From("jsFolder") . Import("MyScript", "MyOhterScript") . And(DoStuff)


DoStuff is a function that do something with loaded scripts.

What else You should do?

You could load different extension files using second From argument:
From("jsFolder", "php") . Import("MyScript", "MyOhterScript")


This code will load files jsFolder/MyScript.php and jsFolder/MyOtherScript.php so You could use this second argument to add variables (Remote Scripting using GET) or load scripts without cache problems.

From("jsFolder", "js".concat("?", Math.random() * 123456789)) . Import("MyScript")


Do You need an example page?
Here there's basic example using a callback while in this page there's an uncached dnamic script load.

I hope You'll like this "Python style" like JavaScript function and finally, You could even load external scripts using an uri instead of folder

From("http://example.com/js").Import("HisScript")



Update - 13/04/2007
I uploaded last revisited version in devpro.

This version fixes different external sources size problem and calls specified callback only when every external script is completely loaded and is available.

This last version send as callback arguments every script created to include each external source.

Please visit new demo page to view an example, where 2 external sources are loaded (forced without cache) and have different sizes :)