CrxOop uses javascript features to provide the OOP features CrxOop provides. It is not a new language, and hence, it is susceptable to javascript's own features, whether good or bad. The 'instances' CrxOop creates are just javascript objects, and unless you are careful about what you are doing, the effect could break, which will break the integrity of the application, and break security when it comes to secure applications.
CrxOop instances, as mentioned earlier, are made of private memory sectors, and public memory sectors. The private sectors contain the class members declared as private, and the public sectors contain the class members declared as public. In other words, unlike other languages where private and public accessors are enforced by the compiler or interpretor, CrxOop's enforcement happens during runtime by carefull memory layout.
Two issues are to be kept in mind. One, the built instances could be modified during runtime, changing them from the class imprints that they are made from. Imagine passing a password to a secure function on an instnace, where the function is not the function you think it is. This issue is resolved by CrxOop using javascript's own object locking mechanisms. Needless to say, older browsers, roughly IE8 era, might suffer. However, exploiting this on the older browsers is not an easy matter, and with carefull programming should be impossible. In our example, making the secure function private is all that is needed. Please also see the section on CrxOop modes.
The second issue is leaking of the private memory sectors of an instance. This can happen through either passing of dangerous Class Keywords, including 'this', to other functions. Please see the section on Class Keywords for more information. Or infestation of the private sector by assigning a malicious function to a class private instance variable. Consider the following:
crx_registerClass("ExampleClass",
{
PRIVATE:
{
VARS:
{
"privateVar1": "privateVar1",
"privateVar2": null
}
},
PUBLIC:
{
FUNCTIONS:
{
"setPrivateVar2": function(pFunction)
{
this.privateVar2 = pFunction;
},
"printPrivateVar": function()
{
console.log(this.privateVar1);
},
"test": function()
{
this.privateVar2();
}
}
}
});
var vInstance = crx_new("ExampleClass");
vInstance.printPrivateVar();
//START: ATTACKER CODE
function maliciousCode()
{console.log(this.privateVar1);}
vInstance.setPrivateVar2(maliciousCode);
//END: ATTACKER CODE
vInstance.test();
crx_registerClass("ExampleClass",
{
"VERBOSE": 1,
"private var privateVar1": "privateVar1",
"private var privateVar2": null,
"public function setPrivateVar2": function(pFunction)
{
this.privateVar2 = pFunction;
},
"public function printPrivateVar": function()
{
console.log(this.privateVar1);
},
"public function test": function()
{
this.privateVar2();
}
});
var vInstance = crx_new("ExampleClass");
vInstance.printPrivateVar();
//START: ATTACKER CODE
function maliciousCode()
{console.log(this.privateVar1);}
vInstance.setPrivateVar2(maliciousCode);
//END: ATTACKER CODE
vInstance.test();
Notice how the malicious function maliciousCode() managed to read the private variable privateVar1, and all it took was the reading of "this". Very serious, but maybe not so because exploiting this can be difficult. The attacker still needs to access the private variable where his malicious code was stored, which in our case was conveniently executed by the test function. However, this author does not know if there are other ways to exploit this, but one thing for certain, if not a security risk, this can lead to bad habbits. Avoid exploiting this yourself on your own classes to try and change the meaning of accessors.
When it comes to security, despite the above skepticism, do not play with fire. And when it comes to integrity, avoid exploiting this with your own code to keep code well defined and clean. To stop such things, CrxOop provides the function crxOop.var(). crxOop.var takes a single argument, and if it is a function returns a safe modification of the function, and if not returns the argument as it is.
crx_registerClass("ExampleClass",
{
PRIVATE:
{
VARS:
{
"privateVar1": "privateVar1",
"privateVar2": null
}
},
PUBLIC:
{
FUNCTIONS:
{
"setPrivateVar2": function(pFunction)
{
//SECURITY
this.privateVar2 = crxOop.var(pFunction);
},
"printPrivateVar": function()
{
console.log(this.privateVar1);
},
"test": function()
{
this.privateVar2();
}
}
}
});
var vInstance = crx_new("ExampleClass");
vInstance.printPrivateVar();
//START: ATTACKER CODE
function maliciousCode()
{console.log(this.privateVar1);}
vInstance.setPrivateVar2(maliciousCode);
//END: ATTACKER CODE
vInstance.test();
crx_registerClass("ExampleClass",
{
"VERBOSE": 1,
"private var privateVar1": "privateVar1",
"private var privateVar2": null,
"public function setPrivateVar2": function(pFunction)
{
//SECURITY
this.privateVar2 = crxOop.var(pFunction);
},
"public function printPrivateVar": function()
{
console.log(this.privateVar1);
},
"public function test": function()
{
this.privateVar2();
}
});
var vInstance = crx_new("ExampleClass");
vInstance.printPrivateVar();
//START: ATTACKER CODE
function maliciousCode()
{console.log(this.privateVar1);}
vInstance.setPrivateVar2(maliciousCode);
//END: ATTACKER CODE
vInstance.test();
The code works now as expected. crxOop.var simply binds functions' 'this' to something safe. You can use javascripts own facilities if you like, but the advantage to crxOop.var is that it works with older browsers, and it makes the functions work with CrxOop's internal halt signal. This means, if there is a fatal error issued by CrxOop, those functions will also halt.