DEV Community 👩‍💻👨‍💻

Anthony Smith
Anthony Smith

Posted on • Updated on

Obfuscating JavaScript code with Node.js

As a developer, you spend a lot of time building, developing, and debugging your code. The last thing you want is for someone else to have the ability to steal all of your hard work and reuse it somewhere else. Thankfully, there is a common practice called code obfuscation that can help protect your work from the eyes of the public.



Obfuscation is a technique that deliberately obfuscates the source code of a JavaScript file which makes it difficult for humans to understand. It is similar to encryption, but a computer program can still understand the code and can execute it.

Analyzing obfuscated code

function _0x33bc(_0x357a49, _0x4d043b) {
    var _0x3af57c = _0x3af5();
    return _0x33bc = function (_0x33bc59, _0x2d7f6b) {
        _0x33bc59 = _0x33bc59 - 0xac;
        var _0x433c74 = _0x3af57c[_0x33bc59];
        return _0x433c74;
    }, _0x33bc(_0x357a49, _0x4d043b);
}
var _0x5b0965 = _0x33bc;

function _0x3af5() {
    var _0x16d4f2 = ['2293120DDXwAC', '5tguhIh', 'ExpressJS', '32097acJbHr', '1234303tDdtZs', 'HTML', '51273EoArEE', 'CSS', 'JavaScript', '3214428qqnLuG', 'MongoDB', '40qdyzEo', 'Smith', '252346qcgJWs', '292cvJCiT', 'Anthony', 'PHP', '2392880xWQHuO', 'Full\x20Stack\x20Developer'];
    _0x3af5 = function () {
        return _0x16d4f2;
    };
    return _0x3af5();
}(function (_0x36cba0, _0x8d74e1) {
    var _0x4b315b = _0x33bc,
        _0x589073 = _0x36cba0();
    while (!![]) {
        try {
            var _0x243a48 = -parseInt(_0x4b315b(0xb8)) / 0x1 * (-parseInt(_0x4b315b(0xb1)) / 0x2) + -parseInt(_0x4b315b(0xba)) / 0x3 * (parseInt(_0x4b315b(0xb2)) / 0x4) + parseInt(_0x4b315b(0xb5)) / 0x5 + parseInt(_0x4b315b(0xad)) / 0x6 + -parseInt(_0x4b315b(0xbb)) / 0x7 + -parseInt(_0x4b315b(0xaf)) / 0x8 * (parseInt(_0x4b315b(0xbd)) / 0x9) + -parseInt(_0x4b315b(0xb7)) / 0xa;
            if (_0x243a48 === _0x8d74e1) break;
            else _0x589073['push'](_0x589073['shift']());
        } catch (_0x513014) {
            _0x589073['push'](_0x589073['shift']());
        }
    }
}(_0x3af5, 0x68fca));
var person = {
    'first_name': _0x5b0965(0xb3),
    'last_name': _0x5b0965(0xb0),
    'occupation': _0x5b0965(0xb6),
    'languages': [_0x5b0965(0xac), _0x5b0965(0xbc), _0x5b0965(0xbe), 'React', _0x5b0965(0xb4), 'NodeJS', _0x5b0965(0xae), _0x5b0965(0xb9)]
};
Enter fullscreen mode Exit fullscreen mode

That's some code that is obfuscated. Pretty hard to understand isn't it? Most likely, unless you are some super programming genius, you will not be able to understand it. You'll have to read it really carefully to understand what is going on.

Here is the original code:

var person = {
    first_name : "Anthony",
    last_name : "Smith",
    occupation : "Full Stack Developer",
    languages: ["JavaScript", "HTML", "CSS", "React", "PHP","NodeJS", "MongoDB","ExpressJS"],
};
Enter fullscreen mode Exit fullscreen mode

Looks pretty different, doesn't it? Even though this is just a simple object it can be easily stolen and re-used somewhere else without your permission. If this was company data that you dont want the world to see, obfuscating is the way to go. This is also useful for people who sell code on platforms like ThemeForest, Template Monster, etc where your code could easily be copied from the browser and pasted into a text editor, however with an obfuscator it can still be copied but it would be extremely hard to read and decrypt.

In this article, I'll be showing you how you can obfuscate your code with the JavaScript Obfuscator library in Node.js.

When and why should you obfuscate your JavaScript code?

One of the most frustrating things about JavaScript is that it is easy to understand by most developers which means it can be stolen and reused somewhere else without the developer's permission. The last thing you want is for someone else to capture and reuse all the code YOU wrote.



I think it makes sense to obfuscate, to make it at least harder if not impossible for someone to disassemble. Also, I think it makes sense for products involving a large customer base where you do not want your competitors to know much about your products.

How to obfuscate your JavaScript code?

We're going to be using the Node.js and the JavaScript Obfuscator module to obfuscate our JavaScript code. The javaScript obfuscator module is a free and open source tool with a wide number of features that can protect your code from being stolen.

Key Features:

  • control flow flattening
  • various code transformations
  • CLI options
  • Has no restrictions or limits
  • Can run on your local machine or on a remote server as it does not require any internet connection
  • variables renaming
  • dead code injection

Installation:

npm install javascript-obfuscator
Enter fullscreen mode Exit fullscreen mode

After installing the module, you can require it in your code using require("javascript-obfuscator").

Using the module:

Now we can begin using the obfuscator module. We must first create an instance of the obfuscator module, from there, we can use the obfuscate method to obfuscate our code. It expects a first argument which is the code to obfuscate and a second argument which is an object containing the options to use.

// Require the JavaScript obfuscator
var JavaScriptObfuscator = require('javascript-obfuscator');

// Obfuscate the code providen as first argument
var obfuscationResult = JavaScriptObfuscator.obfuscate(`
function myfunction() {
  console.log("function");
};

myfunction();

function calculate(x, y, op) {
  var answer;
  if ( op = "add" ) {
    answer = x + y;
  };
  else if ( op = "sub" ) {
    answer = x - y;
  };
  else if ( op = "multi" ) {
    answer = x * y;
  };
  else if ( op = "divide" ) {
    answer = x / y;
  };
  else {
    answer = "Error";
  };
  return answer;
};
`);

// Display obfuscated result
console.log(obfuscationResult.getObfuscatedCode());
Enter fullscreen mode Exit fullscreen mode

Options:

You can customize the obfuscator module by passing an object containing the options to use.

JavaScriptObfuscator.obfuscate(YourCode, {
    compact: true,
    controlFlowFlattening: false,
    controlFlowFlatteningThreshold: 0.75,
    deadCodeInjection: false,
    deadCodeInjectionThreshold: 0.4,
    debugProtection: false,
    debugProtectionInterval: false,
    disableConsoleOutput: false,
    domainLock: [],
    log: false,
    mangle: false,
    renameGlobals: false,
    reservedNames: [],
    rotateStringArray: true,
    seed: 0,
    selfDefending: false,
    sourceMap: false,
    sourceMapBaseUrl: '',
    sourceMapFileName: '',
    sourceMapMode: 'separate',
    stringArray: true,
    stringArrayEncoding: false,
    stringArrayThreshold: 0.75,
    target: 'browser',
    unicodeEscapeSequence: false
});
Enter fullscreen mode Exit fullscreen mode

You should check out the official documentation of the library to see all the new options that are presently available. You can also check out the JavaScript Obfuscator website to see all the options that are currently available. Currently, they provide presets which include a feeling of "low", "medium", "high" and "highest".

A. Low Obfuscation

{
    compact: true,
    controlFlowFlattening: false,
    deadCodeInjection: false,
    debugProtection: false,
    debugProtectionInterval: false,
    disableConsoleOutput: true,
    log: false,
    mangle: true,
    renameGlobals: false,
    rotateStringArray: true,
    selfDefending: true,
    stringArray: true,
    stringArrayEncoding: false,
    stringArrayThreshold: 0.75,
    unicodeEscapeSequence: false
}
Enter fullscreen mode Exit fullscreen mode

B. Medium Obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.75,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 0.4,
    debugProtection: false,
    debugProtectionInterval: false,
    disableConsoleOutput: true,
    log: false,
    mangle: false,
    renameGlobals: false,
    rotateStringArray: true,
    selfDefending: true,
    stringArray: true,
    stringArrayEncoding: 'base64',
    stringArrayThreshold: 0.75,
    unicodeEscapeSequence: false
}
Enter fullscreen mode Exit fullscreen mode

C High Obfuscation

{
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 1,
    debugProtection: true,
    debugProtectionInterval: true,
    disableConsoleOutput: true,
    log: false,
    mangle: false,
    renameGlobals: false,
    rotateStringArray: true,
    selfDefending: true,
    stringArray: true,
    stringArrayEncoding: 'rc4',
    stringArrayThreshold: 1,
    unicodeEscapeSequence: false
}
Enter fullscreen mode Exit fullscreen mode

Try it out!

We're going to go ahead and read the content of a JS file and then obfuscate it.

// Require Filesystem module
var fs = require("fs");

// Require the Obfuscator Module
var JavaScriptObfuscator = require('javascript-obfuscator');

// Read the file of your original JavaScript Code as text
fs.readFile('./your-original-code.js', "UTF-8", function(err, data) {
    if (err) {
        throw err;
    }

    // Obfuscate content of the JS file
    var obfuscationResult = JavaScriptObfuscator.obfuscate(data);

    // Write the obfuscated code into a new file
    fs.writeFile('./your-code-obfuscated.js', obfuscationResult.getObfuscatedCode() , function(err) {
        if(err) {
            return console.log(err);
        }

        console.log("The file was saved!");
    });
});
Enter fullscreen mode Exit fullscreen mode

As you can see, the above code is now obfuscated making it much harder for humans to understand. This is a great way to protect your JavaScript code from hackers and prying eyes.

Obfuscation is a great way to hide business logic from the outside world, and it will also make the size of your js file much smaller so it can be more easily transferred.

Oldest comments (0)

🤯

"I made 10x faster JSON.stringify() functions, even type safe"

☝️ Must read for JS devs