Learn how to obfuscate some JS Code using the JavaScript Obfuscator library in Node.js


Analyze the following JavaScript code:

(function(_0x1f87a3, _0x3799c5) {
    var _0x17ebae = function(_0x55b076) {
        while (--_0x55b076) {
            _0x1f87a3['push'](_0x1f87a3['shift']());
        }
    };
    _0x17ebae(++_0x3799c5);
}(_0xaec5, 0x67));
var _0x5aec = function(_0x3dd15e, _0x1f0015) {
    _0x3dd15e = _0x3dd15e - 0x0;
    var _0x231fd0 = _0xaec5[_0x3dd15e];
    return _0x231fd0;
};
(function() {
    var _0x1e950d = '5' - 0x3;
    var _0x137c62 = '5' + 0x3;
    var _0x277681 = '5' + -'2';
    var _0x531dc9 = ['10', '10', '10', '10', '10'][_0x5aec('0x0')](parseInt);
    var _0x1db9e4 = 'foo\x20' + 0x1 + 0x1;
    console[_0x5aec('0x1')](_0x1e950d);
    console[_0x5aec('0x1')](_0x137c62);
    console[_0x5aec('0x1')](_0x277681);
    console[_0x5aec('0x1')](_0x531dc9);
    console[_0x5aec('0x1')](_0x1db9e4);
}());

Just kidding, unless you are a computer or a privileged programming genius/computer, you won't be able to understand in a couple of seconds what the previous JS code means or does, you'll have to read it carefully to understand what it does. Well, the previous total valid JavaScript code is an obfuscated version of the following code:

(function(){
    var variable1 = '5' - 3;
    var variable2 = '5' + 3;
    var variable3 = '5' + - '2';
    var variable4 = ['10','10','10','10','10'].map(parseInt);
    var variable5 = 'foo ' + 1 + 1;
    console.log(variable1);
    console.log(variable2);
    console.log(variable3);
    console.log(variable4);
    console.log(variable5);
})();

It looks pretty different isn't it? The obfuscation of your JavaScript code can help you with the non-allowed usage of your code in other places. This is pretty useful for people that sell code on platforms like Themeforest, where your code can be easily copied from the browser, however, with an obfuscator it can be copied but hard readable (even worse than the minification). In this article, we'll show you how you can obfuscate your code in Node.js using the JavaScript obfuscator module.

Obfuscate JavaScript Online

If you want to test the tool before implementing it on your own, you can use this online JavaScript Obfuscator that uses the same library in the background but runs on the browser.

1. Install the JavaScript Obfuscator Module

To proceed with the obfuscation of any JS code (for the browser, node.js, etc) with Node.js, you will need to rely on the JavaScript obfuscator module. JavaScript obfuscator is a powerful free obfuscator for JavaScript and Node.js with a wide number of features that provide protection for your source code. This module:

  • has no limits or restrictions.
  • runs on your local machine - does not send data to a server.
  • compatible with es2015, es2016 and partially es2017.

You can install this module using the following command:

npm install javascript-obfuscator

After the installation you will be able to require the module in your scripts using require("javascript-obfuscator"). The obfuscator is free and open source (BSD-2-Clause licensed) and is written in TypeScript, you can see an online implementation of the module here. For more information about this library, please visit the official repository at Github here

2. Using the Obfuscator

The logic to obfuscate some code with the module is really simple. You create an instance of the Module, from the instance you can use the obfuscate method that expects as first argument the code that you want to obfuscate. This method returns the obfuscated synchronously. Through a series of transformations, such as variable / function / arguments renaming, strings removal, and others, your source code is transformed into something unreadable, while working exactly as before:

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

// Obfuscate the code providen as first argument
var obfuscationResult = JavaScriptObfuscator.obfuscate(`
(function(){
    var variable1 = '5' - 3;
    var variable2 = '5' + 3;
    var variable3 = '5' + - '2';
    var variable4 = ['10','10','10','10','10'].map(parseInt);
    var variable5 = 'foo ' + 1 + 1;
    console.log(variable1);
    console.log(variable2);
    console.log(variable3);
    console.log(variable4);
    console.log(variable5);
})();
`);

// Display obfuscated result
console.log(obfuscationResult.getObfuscatedCode());

Obfuscator Options

The obfuscator can be customized if you provide the configuration object as second argument in the obfuscate method. The following snippet shows all the available properties on the module:

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
});

It's worth to read the documentation of the library as in the future new options may appear. The official repository offers already made presets to provide a feeling of "low", "medium" or "high" obfuscation with a special combination of options. Note that the better the obfuscation is, the slower the processing step is:

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
}

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
}

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
}

Example

In the following example we're going to read the content of a JS file and we'll write a new one with the obfuscated version of the code:

// 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!");
    });
});

Remember that, while it's almost impossible to recover the exact original source code from the obfuscated version, someone with the time, knowledge and patience can reverse-engineer it. The example doesn't use a special obfuscation but the default, so if you want a custom obfuscation, provide a configuration object.

Happy coding !


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors