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 View 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.
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. 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 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.
Try out more than one obfuscator (even a commercial one) by Googling, for instance, and see which one works best for you. |