I posted this to the websec mailing list and I thought I'd post it here to see if anyone could beat it:-
Over the last few months I've been developing and rewriting (a lot) JSReg but now hopefully I'm finally getting somewhere. The goal was to produce a sandboxed version of Javascript within Javascript itself because I need a sandbox for some projects I'm working on and I don't want the overhead of another language.
My sandbox works with prefixes and suffixes so "x" becomes "$x$" and any reference to objects becomes $obj[$+'yourref'+$]. In addition I only allow certain functions/properties based on a whitelist (so stuff like constructor isn't supported). I also create safe functions which run some checks to prevent window leakage, for example take (1,[].sort)().alert(1) here we leak to window. I protect against this sort of attack by whitelisting native functions to disallow no or null arguments with the option to override per function (then an additional check is performed on the object).
JSReg contains a special object called "globals", I use this to rewrite your javascript code so for example 'test' becomes globals.string('test') this produces a special prototyped version of the string which can be used later. Native functions are also supported this way by calling their name e.g. globals.alert(1)
So how does the code look once it's been JSReg'd well here is a code sample:-
function x(){ var m=1; this.getM=function(){ return m; } }; y=new x; y.getM()
Which gets rewritten to:-
function $x$(){ var $m$=globals.number(1);this.$getM$=function(){ return $m$; } };$y$=new $x$;$y$.$getM$()
As you may have noticed I allow "this" to be used in this way but I will disallow assignment or return the value of "this", I may improve this in future once I'm certain that it is safe to use.
At the moment I allow JSReg globals to be overwritten but I might prevent this at the regexp level or with setters and there are a few problems when not finishing a statement with a ";". Finally there's a limitation regarding the scope, at the moment the prefixes and suffixes are in the global scope so $x$ is actually window.$x$, I plan to get round this somehow so that $x$ is assigned to a object I'm still working that out.
Any comments or suggestions are of course welcome but specifically I'm looking for hacks to window or glaring errors in my RegExps. If you can hack JSReg so that it returns window please let me know
Once I'm confident that it is a secure sandbox, I shall release it as open source. You can have a go here:-
http://www.businessinfo.co.uk/labs/jsreg/jsreg.html
------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [
www.businessinfo.co.uk]
blog : [
www.thespanner.co.uk]
Hackvertor : [
hackvertor.co.uk]