Obfuscation (extended comment)
This is to extend on a comment I made previously which has attracted a number of comments from users wishing to know more. As such I've split it out from the previous answer.
A large number of Web Apps are Javascript based (centric) and as such the ability for reverse engineering is huge as the client has access to the really important part of the code, which typically handles the UI and directs the backend in most of its tasks. At some point the script is likely to handle, or fire, traffic containing much of the data the App deals with, and as such it is easy to expose a lot of the underlying structure of the wider application. One often overlooked technique to protect your own IP is to obfuscate the code, hiding the true purpose of the variables, functions and objects you've written.
Obfuscation is a technique used to
complicate code. Obfuscation makes
code harder to understand when it is
de-compiled, but it typically has no
affect on the functionality of the
code. Obfuscation programs can be used
to protect Java programs by making
them harder to reverse-engineer.
Obfuscation: http://en.wikipedia.org/wiki/Obfuscated_code
Using PHP to obfuscate your Javascript (JS) is relatively easy, you can simply create an index of terms to replace, use PHP to open your script replace those terms with their obfuscated counterparts and write the result.
Obfuscating code on the fly in PHP is also easy, though it creates some delay (depending on the size of your files/index). Obfuscating your JS on the fly means values change between visits/page views, adding an additional layer of noise, as the underlying code appears to alter every time the page is loaded.
To illustrate how one may introduce obfuscation into their app, I will examine one possible implementation, this utilises a great great PHP script, PHP Minify, which offers further benefits that will be explained.
Say we have 3 Javascript files, JS1, JS2 and JS3. These scripts have to appear in the order 1, 2, 3- and at present are linked seperately in the header of the master HTML (or PHP) file which delivers our application to the user. JS1 and JS2 are off the shelf external frameworks, such as (eg) jQuery and Prototype (ignore the fact you likely wouldnt have both in your App). JS3 is YOUR javascript, where you utilise the functionality in JS1 and JS2 using your own functions, variables, objects, classes etc. It is your intellectual property (IP) and/or must be obfuscated for legal, financial or selfish(!) reasons.
Obviously, it isnt helpful for us to obfuscate our JS, then have to develop it further. There is a reason we call our functions things like 'function_to_save_secret_info', it makes it easier when we are writing our code (though this highlights why one may want to obfuscate). The ideal would therefore be to keep our JS file that we develop, with the common sense naming, then every time a user requests the master HTML/PHP page, an obfuscated version of this is created on the fly and served. But how do we do this?
One of the best ways is using PHP Minify (http://code.google.com/p/minify/). PHP Minify has a number of advantages. One of these is the ability to group and serve scripts as a single bundle. So, instead of linking to JS1, JS2 and JS3 in our header, we use PHP Minify to set up a group which comprises these three, we link to this group in the header so only have a single reference. Advantages of this include:
- Less HTTP requests, faster loading and better caching (one not three)
- PHP Minify automatically YUI compresses scripts within groups, making load times far faster (also a type of obfuscation in its way)
- Easier management of our JS, altering groups is a breeze
- Less straight forward to inspect our code.
Once we do this, our master page links to our PHP Minify group, which is great- but we effectively are still serving the same content (all be it in a better way).
However, what we can do now is build our obfuscation routine for JS3. In the groupsConfig.php script where we define our script groups in PHP Minify, we change the group, replacing JS3.js with JS3.obfuscated.js. However, we still have the plain english version of JS3.js, JS3.obfuscated.js does not exist.
So basically our main/master HTML/PHP page links to our JS group in its header, which is a reference to PHP Minify where the group is defined as :
JS1.js
JS2.js
JS3.obfuscated.js
What we now need to do is build a key table/function to obfuscate JS3 and outputs JS3.obfuscated.js. At the simplest level, what we do is write PHP which contains the following (for example, this is not the best code):
$terms_to_obfuscate=array(
'my_secret_function',
'my_secret_object',
'my_secret_variable'
)
foreach ($terms_to_obfuscate as $key => $value) {
//replace base64_encode(md5(rand(0,999))) with whatever you want to produce an obfuscated term
$obfuscated_terms[]=base64_encode(md5(rand(0,999)));
}
$source_js=file_get_contents('JS3.js');
$fh = fopen('JS3.obfuscated.js', 'w+') or die("can't open file");
$obfuscated_js = str_replace($terms_to_obfuscate, $obfuscated_terms, $source_js);
fwrite($fh, $obfuscated_js);
fclose($fh);
What this script will do, is open our english language version of JS3, look for the terms we want to obfuscate and replace with randomised content, writing the output to JS3.obfuscated.js. If we place this code ABOVE the group definition in PHP Minify, it will run each time the JS group is called...so each time the underlying master HTML/PHP page for our application loads, our script is randomly obfuscated. Note, this may not be the best implementation in all cases, this is illustrative only.
This is only one possible way of accomplishing obfuscation, but what we now have is compressed JS served faster to our users, randomly obfuscated, and we can still develop our script in 'plain english'. All we have to do is update our list of terms to obfuscate. There are better ways of doing this, this is meant only as an illustration and not a definite, of the general ideas behind the concept.
It is important to note, that obfuscation may only be appropriate for certain projects (it is not particularly open source by any means), and is not a total protection against reverse engineering, but should be viewed as more of a stumbling block for those less determined.