Hack 72. Obfuscate JavaScript and Ajax Code


Use a free application to obfuscate or hide Ajax source code.

Some companies or developers do not want to expose their JavaScript source code for anyone to cut, paste, and reuse. They want to make the code more difficult, if not exactly impossible, to reverse engineer. As we all know, it is very easy to look at the JavaScript source code for a web page by choosing the ViewView Source (in Safari) or ViewPage Source (in Firefox) command from the browser menu, or by requesting the URL for any .js file that the page imports.

However, development teams generally do not want to give away code that represents a big investment or a cool new proprietary technology. To this end, free-of-charge and commercial software is available to make the source code very difficult to read, but still work for your application in the browser. These programs are called code obfuscators.

Software is also available for altering the code to make its download footprint smaller. This hack focuses on obfuscation, which effectively reduces the byte-size of the downloaded code as well. Many code obfuscators provide this feature.


Go to a search engine such as Google, and type in "JavaScript obfuscators," and you'll get a load of links for this kind of software. The software used in this hack, JavaScript Chaos Edition (JCE), is available from a company in Stockholm, Sweden named Syntropy Development. This hack uses a free version of Syntropy's commercial product, which is a Java program distributed as a Java Archive (JAR) file. You can download it from http://www.syntropy.se/?ct=downloads.

JCE is very easy to use. Simply launch the JAR file by typing java -jar jce.jar at a command-line prompt. This command generates a GUI application, which Figure 9-3 shows.

Figure 9-3. The JCE obfuscator GUI


Take the JavaScript or HTML that you want to obfuscate (this hack obfuscates only the JavaScript), and paste it into the main window. Then click the Next button to display another screen that lets you choose which functions and variables to obfuscate. Figure 9-4 shows this screen.

Figure 9-4. Scrambled code and home fries


"Obfuscation" in this program means that the functions will be given truncated, nonsensical names, such as vH. You can choose to obfuscate all the functions and variables, to remove comments and/or linefeeds, and to use short identifiers. You then paste the altered code into a new file for your HTML to import.

If any HTML element attributes contain JavaScript function calls (as in onsubmit="myfunc(obj)", you have to ensure that the attributes use the new obfuscated function names. You'll have to make these changes in the HTML source code by hand, if you are just using this tool to obfuscate the imported JavaScript file.


The result is meaningless function and variable names mushed together into one giant line. The altered code by no means represents a heavy-duty security measure like encryption; it just generates code that is somewhat harder to crack and analyze for its functionality. At the very least, a large, nontrivial JavaScript program that has been obfuscated poses a major headache to pick apart.

Another problem that can arise from obfuscation is that sometimes the obfuscator changes the name of an object property inside your JavaScript code, such as the XMLHttpRequest object's onreadystatechange event handler. In this case, you have to hunt through the altered code to make the change back to the correct name, or the XMLHttpRequest object will not function properly.


Another limitation (rather than a problem) with obfuscation is that you cannot alter the URLs that are targeted by the XMLHttpRequest object. You have to rely on server-side security strategies to protect these URLs from unauthorized use.

Here is some JavaScript code for dynamic message generation. The actual code function does not matter here; we're just showing the before and after effects of obfuscation. Here's the "before" code:

var request,timeoutId; function eMsg(msg,sColor){     var div = document.getElementById("message");     div.style.color=sColor;     div.style.fontSize="0.9em";     //remove old messages     div.innerHTML="";     div.appendChild(document.createTextNode(msg)); } function checkIt(val){        if (val.length < 3) {eMsg(             "Please enter a valid value for the user name","red")     }     else{         url="http://10.0.1.2:8080/parkerriver/s/checker?email=                 "+encodeURIComponent(val);         httpRequest("GET",url);     } } function httpRequest(reqType,url){     //Mozilla-based browsers     if(window.XMLHttpRequest){         request = new XMLHttpRequest(  );         request.onreadystatechange=handleCheck;         request.open(reqType,url,true);         timeoutId = setTimeout(timesUp,10000);         request.send(null);           }     //for Internet Explorer     else if (window.ActiveXObject){         request=new ActiveXObject("Microsoft.XMLHTTP");         if(request){             request.onreadystatechange=handleCheck;             request.open(reqType,url,true);             timeoutId = setTimeout(timesUp,10000);             request.send(null);         }     } } //event handler for XMLHttpRequest function handleCheck(  ){     var usedTag,msg, answer,xmlReturnVal;     if(request.readyState == 4){         clearTimeout(timeoutId);         if(request.status == 200){             //Implement Document object in DOM             //last 15-20 code lines snipped for brevity...

And here's the code after scrambling it with the obfuscator:

<!-- This script has been obfuscated with Syntropy's  JCE - Javascript  Chaos Engine which can be downloaded at http://www.syntropy.se. JCE is  free to use if this comment is not removed. --> var dk,DS;function pv(Sg,IF){var Ug =  document.getElementById("message");Ug.style.color=IF;Ug.style.fontSize= "0.9em";Ug.innerHTML="";Ug.appendChild(document.createTextNode(Sg));} function jA(vX){if (vX.length < 3) {pv(;"Please enter a valid value  for the user name","red")}else{hp="http:;"+encodeURIComponent(vX); eo("GET",hp);}}function eo(vh,hp){if(window.XMLHttpRequest){dk =  new XMLHttpRequest(  );dk.lg=PS;dk.open(vh,hp,true);DS = setTimeout(eR,10000); dk.send(null);}else if (window.ActiveXObject){dk=new ActiveXObject ("Microsoft.XMLHTTP");if(dk){dk.lg=PS;dk.open(vh,hp,true);DS =  setTimeout(eR,10000);dk.send(null);}}}function PS(  ){var Yj,Sg,  wL,oY;if(dk.readyState == 4){clearTimeout(DS);if(dk.status == 200){oY =  dk.responseXML;Yj = oY.getElementsByTagName(;"is_used")[0];wL=  Yj.childNodes[0].data;if(wL==true){ pv(;"The user name you have chosen  is not available. "+"Kindly try again. ","red");  }else { pv("Your new user  name has been saved.","blue"); }} else {alert("A problem occurred with  communicating between "+"the XMLHttpRequest object and the server  program.");}}}function eR(  ){dk.abort(  );alert("A problem occurred with  communicating with "+"the server program.");}

As you can see, the resulting code is not eye-friendly and has no comments. Figuring out what a small program like this one is doing certainly won't be impossible, but the effort involved may put off less determined viewers. If the client-side JavaScript is much larger than this example and has dependencies on several files of obfuscated code, the reverse-engineering strain is much greater.

The resulting code, without line breaks and comments and with shorter function names, is smaller (in this short example's case, by about 600 bytes), so it will also be faster to download.


Try out more than one obfuscator (even a commercial one) by Googling, for instance, and see which one works best for you.




Ajax Hacks
Ajax Hacks: Tips & Tools for Creating Responsive Web Sites
ISBN: 0596101694
EAN: 2147483647
Year: 2006
Pages: 138

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net