Javascript Obfuscation: What, Why and How?
Introduction
In this blog, we will be experiencing a beginner level introduction to Obfuscation in Javascript, its use cases and how exactly does it work. But before we begin let me introduce you to the two terms Javascript and Obfuscation for those who are not familiar with them.
What is Javascript?
It is an interpreted and lightweight programming language which you will find in most Dynamic websites these days. It’s one of the most recognised languages in the field of web development and has a variety of use cases in there which can vary from animating some element to handling the user input on the platform. If you’d like to learn more about it do check this awesome resource section put up by Pluralsight.
What is Obfuscation?
In software development, the term Obfuscation basically refers to the technique of making the source code of some application/program difficult to read for some other person, letting the functionality be the same as it was earlier.
Let’s understand this concept from the below example,
In the above image, we can see we have a line saying console.log(“hello world”) which will print hello world in the console tab of the browser. In the next part, we obfuscated that one line of code and converted it into 5 lines as well as made it difficult to read by some other person. The functionality remains the same here and it would print hello world in the console tab of the browser as expected.
Why Obfuscation?
There can be multiple reasons as to why a developer would want to obfuscate their code before using it in some public platform. Some of these reasons are:
- Helps in optimizing the code and provides a faster experience
Although this reason varies from case to case, obfuscating your code can help to shrink the file size of your code as well providing a faster experience to the end-user.
2. Makes reverse engineering a longer process
Javascript is now being used in the majority of websites which provide a dynamic experience to the end-users. Even a small mistake or bug by the developers can introduce great risks to the platform if the attacker can analyze the code and exploit the flaw. So to make the reverse engineering of the code harder, developers would rely on obfuscating their code before pushing it to their public platforms.
3. Prevents people from copying your code
Obfuscating your code can help in preventing people from copying the code of your application without prior authorization. This way the end-user would have a difficult time reading and analyzing the code of the platform thereby decreasing the chance of any code being copied by someone.
How Obfuscation?
Now that you have a basic idea of what exactly is Obfuscation and why would you wanna use it, let us look into three basic techniques of Obfuscating your code.
Case 1: Garbage Code Insertion
Garbage Code Insertion is basically adding dead code into your actual code which would never be executed during runtime. Although this technique isn’t that effective, it would help in making the analysis of the code harder for someone because they would have to go through the garbage code as well which would be placed anywhere in the actual code.
In the image, above you can see that we have a function which converts ASCII characters to hexadecimal format. We have added some portion of garbage code surrounded by comments mentioning where its placed, this code would never be executed but the rest will run like usual. Although what we used here is a very basic type of garbage code, developers would prefer complex functions as part of the garbage code, and the comments wouldn't be added here which is separating the garbage code from the actual code.
Case 2: Encoding (Custom / Pre-defined methods)
In case of a custom function, the developers basically implement their own encoding/decoding functions which would basically take the encoded text as an input and process it during execution. This way these functions would not just serve the purpose of processing simple strings but even dedicated functions in encoded form. In the image on your left-hand side, we can see that we have a function which basically converts Hex bytes to ASCII, we have used it for passing the decoded output like what we can see in the comments part of the code to the eval() function as an argument for execution. In turn, the decoded output would now decode more hex bytes which will be saved as a value for some cookie using the document.cookie property.
In case of using pre-defined functions provided by Javascript, we can basically use functions like atob() “for decoding a base64 encoded string” and btoa() “for encoding a string to base64”. Let’s take an example, in the image on your left-hand side you can see that we have the atob() function decoding a base64 encoded string inside of the eval() function. The eval() function basically executes the argument provided to it as if it was part of the code and in this case, we provided the decoded output of the atob() function which will look like what we have mentioned in the commented part of the code. The function captures the keystrokes by the end-user and prints it in the Console tab.
Case 3: Renaming functions and variables
In this case, the developers rename the functions and variables with gibberish text, hexadecimal patterns etc to make the reading and debugging process harder for someone who’s not familiar with the flow of control of the code. In the image on your left-hand side, we can notice the names of the functions and variables used here, the names are represented in the Hexadecimal format. Changing the names will not affect the flow of control of the code but would just make it harder for someone to analyse it properly because of the similarity in the names. One drawback here is that many debuggers can easily bypass this method and make the analysis comparatively easier.
Summing it up
Obfuscating your code can be helpful at times if implemented correctly and proper techniques are used for its implementation in the code. Obfuscation of phishing pages have been on a rise and attackers are trying to find new ways to bypass the detection mechanisms and debuggers from analysing their code. What we discussed in this blog was a very small portion of what Obfuscation in Javascript is like. There’s a ton of new and advanced techniques to have a strong obfuscation of code in place, I will be attaching a few resources to learn more about obfuscation which would be helpful for the readers to refer to.