Ninja Object Properties in JavaScript
I’ve recently been talking with a good friend about object property names in JS. He had some questions about it, because he was using a Java Framework on the backend which generated some weird JavaScript frontend code. For example it produced several global objects and a few of them had interesting property names in it, something like the following snippet:
{ "Library.debug.DEBUG": 1, "Library.ui.window": function(){ }, "Library.test.whatever": null ... }
I wasn’t sure about how these properties exactly behave at first so I just checked it in the js console. It turned out that setting properties with the object[propertyName] = value; syntax containing dots in the propertyName string does not create sub-objects which was perfectly logical and it was what I expected. So this java library somehow faked an application structure and I think they didn’t know what they were doing when they’ve built it (although there are some pro arguments for using such a structure, the excessive use of bad practices in the rest of their code let me assume that). However, this behaviour lead me to playing around with some different propertyNames, trying some edge cases and after some time I discovered another interesting feature: Ninja Object Properties. A ninja object property is a a property whose name only contains n times a whitespace where n is in the range of 0 to infinite. This gets especially funny if n equals 0. Here is an example:
var x = {}; // let's get some ninja properties x[""] = 1337; x[" "] = 1338; x[" "] = 1339;
And it becomes even funnier to debug, since the Chrome Developer Tools show the properties with equal whitespaces (maybe it strips all whitespaces).
Update
It turned out there is an even more awesome way of having ninja properties by creating the propertyName from charcodes of unicode imperceptible characters. The propertyName seems to be empty but it isn’t (and they also have the same length so they look even more identical), so here you go with your ninja properties ;)
var x = {}; // let's get some ninja properties x[String.fromCharCode(1)] = 1; x[String.fromCharCode(2)] = 2; x[String.fromCharCode(3)] = 3; x[String.fromCharCode(4)] = 4; console.log(x);
Maybe this could be an interesting approach for obfuscating JS-code?
Let me know what you think about it. Anyone wanna write a ninja property obfuscator? :D