JSLint "eval is evil." alternatives - javascript

I am have some JavaScript functions that run on both the client (browser) and the server (within a Java Rhino context). These are small functions - basically little validators that are well defined and don't rely upon globals or closures - self-contained and portable.
Here's an example:
function validPhoneFormat(fullObject, value, params, property) {
var phonePattern = /^\+?([0-9\- \(\)])*$/;
if (value && value.length && !phonePattern.test(value))
return [ {"policyRequirement": "VALID_PHONE_FORMAT"}];
else
return [];
}
To keep things DRY, my server code gets a handle on each of these functions and calls toString() on them, returning them to the browser as part of a JSON object. Something like this:
{ "name" : "phoneNumber",
"policies" : [
{ "policyFunction" : "\nfunction validPhoneFormat(fullObject, value, params, property) {\n var phonePattern = /^\\+?([0-9\\- \\(\\)])*$/;\n if (value && value.length && !phonePattern.test(value)) {\n return [{\"policyRequirement\":\"VALID_PHONE_FORMAT\"}];\n } else {\n return [];\n }\n}\n"
}
]
}
My browser JS code then takes this response and creates an instance of this function in that context, like so:
eval("var policyFunction = " + this.policies[j].policyFunction);
policyFailures = policyFunction.call(this, form2js(this.input.closest("form")[0]), this.input.val(), params, this.property.name));
This all works very well. However, I then run this code through JSLint, and I get back this message:
[ERROR] ValidatorsManager.js:142:37:eval is evil.
I appreciate that often, eval can be dangerous. However, I have no idea how else I could implement such a mechanism without using it. Is there any way I can do this and also pass through the JSLint validator?

I wouldn't worry about it since you are only passing these function strings from the server to the client, and are thus in control of what will be evaluated.
On the other hand, if you were going the other direction and doing the evals of client-passed code on the server, that would be an entirely different story...
Update:
As disabling the validation option in your comment may cause you to miss future errors, I would instead suggest passing the function name rather than the entire function and have the function library mirrored on the server and client. Thus, to call the function, you'd use the following code:
var policyFunction = YourLibraryName[this.policies[j].policyFunctionName];
var policyArguments = this.policies[j].policyArguments;
policyFunction.apply(this, policyArguments);
Update 2:
I was able to validate the following code with JSLint successfully, which essentially allows you to "turn off" validation for the vast minority of cases where eval is appropriate. At the same time, JSLint still validates normal eval calls, and all uses of this method should throw up flags for future developers to avoid using it/refactor it out where possible/as time allows.
var EVAL_IS_BAD__AVOID_THIS = eval;
EVAL_IS_BAD__AVOID_THIS(<yourString>);

Dont encode a function as a string in JSON. JSON is for content, which you are confounding with behavior.
Instead, I suppose you could return JS files instead, which allow real functions:
{ name : "phoneNumber",
policies : [
{ policyFunction : function() {
whateverYouNeed('here');
}
}
]
}
But while that solves the technical issue, it's still not a great idea.
The real solution here is to move your logic out of your content entirely. Import a JS file full of little validation functions and call them as needed based on a dataType property in your JSON or something. If this functions are as small and portable as you say, this should be trivial to accomplish.
Getting your data all tangled up with your code usually leads to pain. You should statically include your JS, then dynamically request/import/query for your JSON data to run through your statically included code.

I would avoid using eval in all situations. There's no reason you can't code around it. Instead of sending code to the client, just keep it hosted on the server in one contained script file.
If that's not doable, you can also have a dynamically generated javascript file then pass in the necessary parameters via the response, and then dynamically load the script on the client side. There's really no reason to use eval.
Hope that helps.

You can use
setInterval("code to be evaluated", 0);
Internally, if you pass setInterval a string it performs a function similar to eval().
However, I wouldn't worry about it. If you KNOW eval() is evil, and take appropriate precautions, it's not really a problem. Eval is similar to GoTo; you just have to be careful and aware of what you're doing to use them properly.

With very little parsing you could have had it like so:
var body = this.policies[j].policyFunction.substr;
body = body.substr(body.indexOf("(") + 1);
var arglist = body.substr(1, body.indexOf(")"));
body = body.substr(arglist.length + 1);
var policyFunction = new Function(arglist, body);
Which would provide a bit of validation, avoid the literal use of eval and work synchronously with the code. But it is surely eval in disguise, and it is prone to XSS attack. If the malevolent person can get their code loaded and evaluated this way - it will not save you. So, really, just don't do it. Add a <script> tag with the proper URL and that would be certainly safer. Well, you know, better safe then sorry.
PS. My apologises if the code above doesn't work, it only shows the intent, I've not tested it, and if I made a mistake at counting parenthesis or some such - well, you should get the idea, I'm not advertising it by any means.

DRY is definitely something I agree with, however there is a point where copy+pasting is more efficient and easy to maintain than referencing the same piece of code.
The code you're saving yourself from writing seems to be equivalent to a clean interface, and simple boiler plate. If the same code is being used on both the server and the client, you could simply pass around the common pieces of the function, rather than the whole function.
Payload:
{
"name": "phoneNumber",
"type": "regexCheck",
"checkData": "/^\\+?([0-9\\- \\(\\)])*$/"
}
if(payload.type === "regexCheck"){
const result = validPhoneFormat(fullObject, value, payload.checkData)
}
function validPhoneFormat(fullObject, value, regexPattern) {
if (value && value.length && !regexPattern.test(value))
return [ {"policyRequirement": "VALID_PHONE_FORMAT"}];
else
return [];
}
This would give you the ability to update the regex from a single location. If the interface changes it does need to be updated in 2 places, but I wouldn't consider that a bad thing. If the client is running code, why hide the structure?
If you really, really want to keep both the object structure and the patterns in one place - extract it to a single API. Have a "ValidatePhoneViaRegex" api endpoint which is called by all places you'd be passing this serialized function to.
If all of this seems like too much effort, set jslint to ignore your piece of code:
"In JSHint 1.0.0 and above you have the ability to ignore any warning with a special option syntax. The identifier of this warning is W061. This means you can tell JSHint to not issue this warning with the /*jshint -W061 */ directive.
In ESLint the rule that generates this warning is named no-eval. You can disable it by setting it to 0, or enable it by setting it to 1."
https://github.com/jamesallardice/jslint-error-explanations/blob/master/message-articles/eval.md
I would prefer to see copy+pasted code, a common api, or receiving parameters and copy+pasted boiler plate than magical functions passed in from the server to be executed.
What happens if you get a cross-browser compatibility error with one of these shared functions?

Well, the first thing to bear in mind is that jsLint does make the point that "it will hurt your feelings". It's designed to point out where you're not following best practices -- but code that isn't perfect can still work just fine; there's no compulsion upon you to follow jsLint's advice.
Having said that, eval is evil, and in virtually all cases there is always a way around using it.
In this case, you could use a library such as require.js, yepnope.js or some other library that is designed to load a script separately. This would allow you to include the javascript functions you need dynamically but without having to eval() them.
There are probably several other solutions as well, but that was the first one that came to my mind.
Hope that helps.

Related

How to prevent script injection attacks

Intro
This topic has been the bane of many questions and answers on StackOverflow -and in many other tech-forums; however, most of them are specific to exact conditions and even worse: "over-all" security in script-injection prevention via dev-tools-console, or dev-tools-elements or even address-bar is said to be "impossible" to protect. This question is to address these issues and serve as current and historical reference as technology improves -or new/better methods are discovered to address browser security issues -specifically related to script-injection attacks.
Concerns
There are many ways to either extract -or manipulate information "on the fly"; specifically, it's very easy to intercept information gathered from input -to be transmitted to the server - regardless of SSL/TLS.
intercept example
Have a look here
Regardless of how "crude" it is, one can easily use the principle to fabricate a template to just copy+paste into an eval() in the browser console to do all kinds of nasty things such as:
console.log() intercepted information in transit via XHR
manipulate POST-data, changing user-references such as UUIDs
feed the target-server alternative GET (& post) request information to either relay (or gain) info by inspecting the JS-code, cookies and headers
This kind of attack "seems" trivial to the untrained eye, but when highly dynamic interfaces are in concern, then this quickly becomes a nightmare -waiting to be exploited.
We all know "you can't trust the front-end" and the server should be responsible for security; however - what about the privacy/security of our beloved visitors? Many people create "some quick app" in JavaScript and either do not know (or care) about the back-end security.
Securing the front-end as well as the back-end would prove formidable against an average attacker, and also lighten the server-load (in many cases).
Efforts
Both Google and Facebook have implemented some ways of mitigating these issues, and they work; so it is NOT "impossible", however, they are very specific to their respective platforms and to implement requires the use of entire frameworks plus a lot of work -only to cover the basics.
Regardless of how "ugly" some of these protection mechanisms may appear; the goal is to help (mitigate/prevent) security issues to some degree, making it difficult for an attacker. As everybody knows by now: "you cannot keep a hacker out, you can only discourage their efforts".
Tools & Requirements
The goal is to have a simple set of tools (functions):
these MUST be in plain (vanilla) javascript
together they should NOT exceed a few lines of code (at most 200)
they have to be immutable, preventing "re-capture" by an attacker
these MUST NOT clash with any (popular) JS frameworks, such as React, Angular, etc
does NOT have to be "pretty", but readable at least, "one-liners" welcome
cross-browser compatible, at least to a good percentile
Runtime Reflection / Introspection
This is a way to address some of these concerns, and I don't claim it's "the best" way (at all), it's an attempt.
If one could intercept some "exploitable" functions and methods and see if "the call" (per call) was made from the server that spawned it, or not, then this could prove useful as then we can see if the call came "from thin air" (dev-tools).
If this approach is to be taken, then first we need a function that grabs the call-stack and discard that which is not FUBU (for us by us). If the result of this function is empty, hazaa! - we did not make the call and we can proceed accordingly.
a word or two
In order to make this as short & simple as possible, the following code examples follow DRYKIS principles, which are:
don't repeat yourself, keep it simple
"less code" welcomes the adept
"too much code & comments" scare away everybody
if you can read code - go ahead and make it pretty
With that said, pardon my "short-hand", explanation will follow
first we need some constants and our stack-getter
const MAIN = window;
const VOID = (function(){}()); // paranoid
const HOST = `https://${location.host}`; // if not `https` then ... ?
const stak = function(x,a, e,s,r,h,o)
{
a=(a||''); e=(new Error('.')); s=e.stack.split('\n'); s.shift(); r=[]; h=HOSTPURL; o=['_fake_']; s.forEach((i)=>
{
if(i.indexOf(h)<0){return}; let p,c,f,l,q; q=1; p=i.trim().split(h); c=p[0].split('#').join('').split('at ').join('').trim();
c=c.split(' ')[0];if(!c){c='anon'}; o.forEach((y)=>{if(((c.indexOf(y)==0)||(c.indexOf('.'+y)>0))&&(a.indexOf(y)<0)){q=0}}); if(!q){return};
p=p[1].split(' '); f=p[0]; if(f.indexOf(':')>0){p=f.split(':'); f=p[0]}else{p=p.pop().split(':')}; if(f=='/'){return};
l=p[1]; r[r.length]=([c,f,l]).join(' ');
});
if(!isNaN(x*1)){return r[x]}; return r;
};
After cringing, bare in mind this was written "on the fly" as "proof of concept", yet tested and it works. Edit as you whish.
stak() - short explanation
the only 2 relevant arguments are the 1st 2, the rest is because .. laziness (short answer)
both arguments are optional
if the 1st arg x is a number then e.g. stack(0) returns the 1st item in the log, or undefined
if the 2nd arg a is either a string -or an array then e.g. stack(undefined, "anonymous") allows "anonymous" even though it was "omitted" in o
the rest of the code just parses the stack quickly, this should work in both webkit & gecko -based browsers (chrome & firefox)
the result is an array of strings, each string is a log-entry separated by a single space as function file line
if the domain-name is not found in a log-entry (part of filename before parsing) then it won't be in the result
by default it ignores filename / (exactly) so if you test this code, putting in a separate .js file will yield better results than in index.html (typically) -or whichever web-root mechanism is used
don't worry about _fake_ for now, it's in the jack function below
now we need some tools
bore() - get/set/rip some value of an object by string reference
const bore = function(o,k,v)
{
if(((typeof k)!='string')||(k.trim().length<1)){return}; // invalid
if(v===VOID){return (new Function("a",`return a.${k}`))(o)}; // get
if(v===null){(new Function("a",`delete a.${k}`))(o); return true}; // rip
(new Function("a","z",`a.${k}=z`))(o,v); return true; // set
};
bake() - shorthand to harden existing object properties (or define new ones)
const bake = function(o,k,v)
{
if(!o||!o.hasOwnProperty){return}; if(v==VOID){v=o[k]};
let c={enumerable:false,configurable:false,writable:false,value:v};
let r=true; try{Object.defineProperty(o,k,c);}catch(e){r=false};
return r;
};
bake & bore - rundown
These are failry self-explanatory, so, some quick examples should suffice
using bore to get a property: console.log(bore(window,"XMLHttpRequest.prototype.open"))
using bore to set a property: bore(window,"XMLHttpRequest.prototype.open",function(){return "foo"})
using bore to rip (destroy carelessly): bore(window,"XMLHttpRequest.prototype.open",null)
using bake to harden an existing property: bake(XMLHttpRequest.prototype,'open')
using bake to define a new (hard) property: bake(XMLHttpRequest.prototype,'bark',function(){return "woof!"})
intercepting functions and constructions
Now we can use all the above to our advantage as we devise a simple yet effective interceptor, by no means "perfect", but it should suffice; explanation follows:
const jack = function(k,v)
{
if(((typeof k)!='string')||!k.trim()){return}; // invalid reference
if(!!v&&((typeof v)!='function')){return}; // invalid callback func
if(!v){return this[k]}; // return existing definition, or undefined
if(k in this){this[k].list[(this[k].list.length)]=v; return}; //add
let h,n; h=k.split('.'); n=h.pop(); h=h.join('.'); // name & holder
this[k]={func:bore(MAIN,k),list:[v]}; // define new callback object
bore(MAIN,k,null); let f={[`_fake_${k}`]:function()
{
let r,j,a,z,q; j='_fake_'; r=stak(0,j); r=(r||'').split(' ')[0];
if(!r.startsWith(j)&&(r.indexOf(`.${j}`)<0)){fail(`:(`);return};
r=jack((r.split(j).pop())); a=([].slice.call(arguments));
for(let p in r.list)
{
if(!r.list.hasOwnProperty(p)||q){continue}; let i,x;
i=r.list[p].toString(); x=(new Function("y",`return {[y]:${i}}[y];`))(j);
q=x.apply(r,a); if(q==VOID){return}; if(!Array.isArray(q)){q=[q]};
z=r.func.apply(this,q);
};
return z;
}}[`_fake_${k}`];
bake(f,'name',`_fake_${k}`); bake((h?bore(MAIN,h):MAIN),n,f);
try{bore(MAIN,k).prototype=Object.create(this[k].func.prototype)}
catch(e){};
}.bind({});
jack() - explanation
it takes 2 arguments, the first as string (used to bore), the second is used as interceptor (function)
the first few comments explain a bit .. the "add" line simply adds another interceptor to the same reference
jack deposes an existing function, stows it away, then use "interceptor-functions" to replay arguments
the interceptors can either return undefined or a value, if no value is returned from any, the original function is not called
the first value returned by an interceptor is used as argument(s) to call the original and return is result to the caller/invoker
that fail(":(") is intentional; an error will be thrown if you don't have that function - only if the jack() failed.
Examples
Let's prevent eval from being used in the console -or address-bar
jack("eval",function(a){if(stak(0)){return a}; alert("having fun?")});
extensibility
If you want a DRY-er way to interface with jack, the following is tested and works well:
const hijack = function(l,f)
{
if(Array.isArray(l)){l.forEach((i)=>{jack(i,f)});return};
};
Now you can intercept in bulk, like this:
hijack(['eval','XMLHttpRequest.prototype.open'],function()
{if(stak(0)){return ([].slice.call(arguments))}; alert("gotcha!")});
A clever attacker may then use the Elements (dev-tool) to modify an attribute of some element, giving it some onclick event, then our interceptor won't catch that; however, we can use a mutation-observer and with that spy on "attribute changes". Upon attribute-change (or new-node) we can check if changes were made FUBU (or not) with our stak() check:
const watchDog=(new MutationObserver(function(l)
{
if(!stak(0)){alert("you again! :D");return};
}));
watchDog.observe(document.documentElement,{childList:true,subtree:true,attributes:true});
Conclusion
These were but a few ways of dealing with a bad problem; though I hope someone finds this useful, and please feel free to edit this answer, or post more (or alternative/better) ways of improving front-end security.

Conditional data structure (object) access

I have a set of JavaScript functions that handle certain objects. All these objects have the following flexibility:
Fields can be accessed like this: data[prop][sub-prop][etc.], OR
Like this (with a type sub-structure): data[TYPE][prop][sub-prop][etc.].
The object is accessed in many places, and the condition (let's call it is_mixed) is relevant everywhere.
I thought of the following alternatives:
Always access data like this: (is_mixed ? data[TYPE] : data)[prop][sub-prop][etc.]
Have a function called getData and always access data like this: getData()[prop][sub-prop][etc.].
The function code would be:
function getData() { return is_mixed ? data[TYPE] : data; }
Run the following on every new input: if (is_mixed) { data = data[TYPE]; }
It seems to me that options 2 and 3 might be copying the object data (which might be big) and performance is important here (I didn't find the literature to support this guess), but option 1 will make the code big and ugly.
Is there a better option? What's the best way to acheive this in terms of performance, code quality and basically best practices?
It seems to me that options 2 and 3 might be copying the JSON content
No, they won't. They both just copy an object reference, which is quick and cheap (like copying a boolean). #2 is of course slightly slower, since it's a function call, but if it's used a lot, any decent JavaScript engine will inline the function anyway, giving you the benefit of modularity at the source level. (It can take thousands of calls to the function in a shortish period of time to make that kick in, though; e.g., a modern engine only bothers with optimization when it looks likely to matter.)

Simple way to check/validate javascript syntax

I have some big set of different javascript-snippets (several thousands), and some of them have some stupid errors in syntax (like unmatching braces/quotes, HTML inside javascript, typos in variable names).
I need a simple way to check JS syntax. I've tried JSLint but it send too many warnings about style, way of variable definitions, etc. (even if i turn off all flags). I don't need to find out style problems, or improve javascript quality, i just need to find obvious syntax errors. Of course i can simply check it in browser/browser console, but i need to do it automatically as the number of that snippets is big.
Add:
JSLint/JSHint reports a lot of problems in the lines that are not 'beauty' but working (i.e. have some potential problems), and can't see the real problems, where the normal compiler will simply report syntax error and stop execution. For example, try to JSLint that code, which has syntax errors on line 4 (unmatched quotes), line 6 (comma required), and line 9 (unexpected <script>).
document.write('something');
a = 0;
if (window.location == 'http://google.com') a = 1;
document.write("aaa='andh"+a+"eded"');
a = {
something: ['a']
something2: ['a']
};
<script>
a = 1;
You could try JSHint, which is less verbose.
Just in case anyone is still looking you could try Esprima,
It only checks syntax, nothing else.
I've found that SpiderMonkey has ability to compile script without executing it, and if compilation failed - it prints error.
So i just created small wrapper for SpiderMonkey
sub checkjs {
my $js = shift;
my ( $js_fh, $js_tmpfile ) = File::Temp::tempfile( 'XXXXXXXXXXXX', EXLOCK => 0, UNLINK => 1, TMPDIR => 1 );
$| = 1;
print $js_fh $js;
close $js_fh;
return qx(js -C -f $js_tmpfile 2>&1);
}
And javascriptlint.com also deals very good in my case. (Thanks to #rajeshkakawat).
Lots of options if you have an exhaustive list of the JSLint errors you do want to capture.
JSLint's code is actually quite good and fairly easy to understand (I'm assuming you already know JavaScript fairly well from your question). You could hack it to only check what you want and to continue no matter how many errors it finds.
You could also write something quickly in Node.js to use JSLint as-is to check every file/snippet quickly and output only those errors you care about.
Just use node --check filename
Semantic Designs' (my company) JavaScript formatter read JS files and formats them. You don't want the formatting part.
To read the files it will format, it uses a full JavaScript parser, which does a complete syntax check (even inside regular expressions). If you run it and simply ignore the formatted result, you get a syntax checker.
You can give it big list of files and it will format all of them. You could use this to batch-check your large set. (If there are any syntax errors, it returns a nonzero error status to a shell).

Measuring pollution of global namespace

Background
I'm trying to refactor some long, ugly Javascript (shamefully, it's my own). I started the project when I started learning Javascript; it was a great learning experience, but there is some total garbage in my code and I employ some rather bad practices, chief among them being heavy pollution of the global namespace / object (in my case, the window object). In my effort to mitigate said pollution, I think it would be helpful to measure it.
Approach
My gut instinct was to simply count the number of objects attached to the window object prior to loading any code, again after loading third-party libraries and lastly after my code has been executed. Then, as I refactor, I would try to reduce the increase that corresponds to loading my code). To do this, I'm using:
console.log(Object.keys(window).length)
at various places in my code. This seems to work alright and I see the number grow, in particular after my own code is loaded. But...
Problem
Just from looking at the contents of the window object in the Chrome Developer console, I can see that its not counting everything attached to the object. I suspect it's not including some more fundamental properties or object types, whether they belong to the browser, a library or my own code. Either way though, can anyone think of a better and more accurate way to measure global namespace pollution that would help in refactoring?
Thanks in advance!
So after some of the comments left by Felix Kling and Lèse majesté, I have found a solution that works well. Prior to loading any libraries or my own code, I create the dashboard global object (my only intentional one) and store a list of objects attached to window via:
var dashboard = {
cache: {
load: Object.getOwnPropertyNames(window)
}
};
Then, after I load all of the libraries but prior to loading any of my own code, I modify the dashboard object, adding the pollution method (within a new debug namespace):
dashboard.debug = {
pollution: (function() {
var pollution,
base = cache.load, // window at load
filter = function(a,b) { // difference of two arrays
return a.filter(function(i) {
return !(b.indexOf(i) > -1);
});
},
library = filter(Object.getOwnPropertyNames(window), base),
custom = function() {
return filter(Object.getOwnPropertyNames(window),
base.concat(library));
};
delete cache.load;
pollution = function() {
console.log('Global namespace polluted with:\n ' +
custom().length + ' custom objects \n ' +
library.length + ' library objects');
return {custom: custom().sort(), library: library.sort()};
};
return pollution;
}())
};
At any point, I can call this method from the console and see
Global namespace polluted with:
53 custom objects
44 library objects
as well as two arrays listing the keys associated with those objects. The base and library snapshots are static, while the current custom measurement (via custom) is dynamic such that if I were to load any custom javascript via AJAX, then I could remeasure and see any new custom "pollution".
The general pattern you've selected works OK from experience. However, there are two things you might need to consider (as additions or alternatives):
Use JsLint.com or JSHint.com with your existing code and look at the errors produced. It should help you spot most if not all of the global variable usage quickly and easily (you'll see errors of 'undefined' variables for example). This is a great simple approach. So, the measurement in this case will be just looking at the total number of issues.
We've found that Chrome can make doing detection of leaking resources on the window object tricky (as things are added during the course of running the page). We've needed to check for example to see if certain properties returned are native by using RegExs: /\s*function \w*\(\) {\s*\[native code\]\s*}\s*/ to spot native code. In some code "leak detection" code we've written, we also try to (in a try catch) obtain the value of a property to verify it's set to a value (and not just undefined). But, that shouldn't be necessary in your case.

I need a Javascript literal syntax converter/deobfuscation tools

I have searched Google for a converter but I did not find anything. Is there any tools available or I must make one to decode my obfuscated JavaScript code ?
I presume there is such a tool but I'm not searching Google with the right keywords.
The code is 3 pages long, this is why I need a tools.
Here is an exemple of the code :
<script>([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[(!![]+[])[!+[]+!+[]+!+[]]+(+(+[])+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+!+[]+[+[]]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]])(([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+
Thank you
This code is fascinating because it seems to use only nine characters ("[]()!+,;" and empty space U+0020) yet has some sophisticated functionality. It appears to use JavaScript's implicit type conversion to coerce arrays into various primitive types and their string representations and then use the characters from those strings to compose other strings which type out the names of functions which are then called.
Consider the following snippet which evaluates to the array filter function:
([][
(![]+[])[+[]] // => "f"
+ ([![]]+[][[]])[+!+[]+[+[]]] // => "i"
+ (![]+[])[!+[]+!+[]] // => "l"
+ (!![]+[])[+[]] // => "t"
+ (!![]+[])[!+[]+!+[]+!+[]] // => "e"
+ (!![]+[])[+!+[]] // => "r"
]) // => function filter() { /* native code */ }
Reconstructing the code as such is time consuming and error prone, so an automated solution is obviously desirable. However, the behavior of this code is so tightly bound to the JavaScript runtime that de-obsfucating it seems to require a JS interpreter to evaluate the code.
I haven't been able to find any tools that will work generally with this sort of encoding. It seems as though you'll have to study the code further and determine any patterns of usage (e.g. reliance on array methods) and figure out how to capture their usage (e.g. by wrapping high-level functions [such as Function.prototype.call]) to trace the code execution for you.
This question has already an accepted answer, but I will still post to clear some things up.
When this idea come up, some guy made a generator to encode JavaScript in this way. It is based on doing []["sort"]["call"]()["eval"](/* big blob of code here */). Therefore, you can decode the results of this encoder easily by removing the sort-call-eval part (i.e. the first 1628 bytes). In this case it produces:
if (document.cookie=="6ffe613e2919f074e477a0a80f95d6a1"){ alert("bravo"); }
else{ document.location="http://www.youtube.com/watch?v=oHg5SJYRHA0"; }
(Funny enough the creator of this code was not even able to compress it properly and save a kilobyte)
There is also an explanation of why this code doesn't work in newer browser anymore: They changed Array.prototype.sort so it does not return a reference to window. As far as I remember, this was the only way to get a reference to window, so this code is kind of broken now.

Categories

Resources