Search This Blog

Thursday, December 20, 2018

Javascript Obfuscation via Jenkins using Node Js and the open source Javascript Obfuscator

A javascript snippet with which I obfuscate javascript files during our building process, via Jenkins (via Node js commands), using the open source Javascript Obfuscator (written in javascript).

var walkSync = function(dir, filelist, dirIgnores, fileIgnores) {
    var fs = fs || require('fs');

    //if dir is to be ignored, return doing nothing
    for (var i = 0; i < dirIgnores.length; i++) {
        if (dir.toLowerCase().endsWith("/" + dirIgnores[i].toLowerCase())) {
            return;
        }
    }

    files = fs.readdirSync(dir);
    filelist = filelist || [];
    //lists file starting names to not obfuscate
    dirIgnores = dirIgnores || [];
    fileIgnores = fileIgnores || [];
    files.forEach(function(file) {

        var fullPath = dir + '/' + file;

        if (fs.statSync(fullPath).isDirectory()) {
            filelist = walkSync(fullPath, filelist, dirIgnores, fileIgnores);
        } else {

            var skip = false;
            for (var i = 0; i < fileIgnores.length; i++) {
                if (file.toLowerCase().startsWith(fileIgnores[i].toLowerCase())) {
                    skip = true;
                    break;
                }
            }

            if (file.endsWith('js') && !skip) {
                filelist.push(fullPath);
            }
        }

    });
    return filelist;
};



var JavaScriptObfuscator = require('javascript-obfuscator');

// folder will be assigned in jenkins via windows batch string replacement
const folder = '#|#';
const fs = require('fs');

//we obfuscate only our javascript code, all third party libraries (located under folder js) are ignored
var files = walkSync(folder, null, ["js"], null /*["jquery", "leaflet", "dx", "knockout", "jstree"]*/ );

//console.log(files);
var errors = [];

for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var jsFileContents = fs.readFileSync(file, 'utf8');

    console.clear();
    console.log('File being obfuscated: ' + file + '...');

    try {
        //obfuscate
        var obfuscationResult = JavaScriptObfuscator.obfuscate(
            jsFileContents,
            /*************************************************************************/
            /* Javascript-obfuscator preset: Medium obsfuscation, optimal performace */
            /*************************************************************************/
            {
                compact: true,
                controlFlowFlattening: true,
                controlFlowFlatteningThreshold: 0.75,
                deadCodeInjection: true,
                deadCodeInjectionThreshold: 0.4,
                debugProtection: false,
                debugProtectionInterval: false,
                disableConsoleOutput: true,
                identifierNamesGenerator: 'hexadecimal',
                log: false,
                renameGlobals: false,
                rotateStringArray: true,
                selfDefending: true,
                stringArray: true,
                stringArrayEncoding: 'base64',
                stringArrayThreshold: 0.75,
                transformObjectKeys: true,
                unicodeEscapeSequence: false
            }
        );

        //obfuscated content
        var obfuscatedJs = obfuscationResult.getObfuscatedCode();

        //fs.writeFileSync(file.replace('.js', '_o.js'), obfuscatedJs, {encoding: 'utf8'});
        fs.writeFileSync(file, obfuscatedJs, {
            encoding: 'utf8'
        });
    } catch (e) {
        errors.push('Error obfuscating ' + file + ': ' + e);
        //console.log('Error obfuscating ' + file + ': ' + e);
    }

}

console.log(files.length + ' files obfuscated. Errors: ' + errors.length);
if (errors.length > 0)
    for (var i = 0; i < errors.length; i++)
        console.log(errors[i]);

No comments:

Post a Comment