Code Monkey home page Code Monkey logo

node-obfuscator's Introduction

maintainer wanted

if you want this package, open an issue or email me











Obfuscator

Build Status Dependency Status

Obfuscate your node packages because your boss says so!

Why?

Because I had this conversation:

me: hi boss. this application should be written in node, not java. node is good and stuff.

boss: oh, okay. node sounds great. what about code protection so people don't steal our software?

me: ...

boss: you can't use node.

... but now:

me: hi boss. first off, code protection is stupid. secondly, java can be decompiled.

boss: but decompiling java is a lot of work.

me: so is un-obfuscating javascript!

Usage

Command Line (installed globally with the -g flag)

$ obfuscator --entry app.js ./app.js ./routes/index.js ./routes/user.js

JavaScript API

var Options = require('obfuscator').Options;
var obfuscator = require('obfuscator').obfuscator;
var fs = require('fs');
var options = new Options([ '/path/to/file1.js', '/path/to/file2.js' ], '/path/to', 'file1.js', true);

// custom compression options
// see https://github.com/mishoo/UglifyJS2/#compressor-options
options.compressor = {
  conditionals: true,
  evaluate: true,
  booleans: true,
  loops: true,
  unused: false,
  hoist_funs: false
};

obfuscator(options, function (err, obfuscated) {
  if (err) {
    throw err;
  }
  fs.writeFile('./cool.js', obfuscated, function (err) {
    if (err) {
      throw err;
    }

    console.log('cool.');
  });
});

Also see acceptance tests or the docs.

How it Works

Think browserify only for node, plus UglifyJs. Your entire project will be concatenated into a single file. This file will contain a stubbed require function, which will handle everything for you. This single file will be run through UglifyJs, making it more difficult to read.

Undoing this process is hopefully as painful as decompiling java bytecode.

Known bugs and limitations

  • everything (including json, subdirectories, etc.) must be in the root of your project.
  • you're not able to use many of the native module's require features; only require.cache and require.resolve have been exposed.
  • you're not able to do silly things with module.
  • dynamically built require()s are not supported; chances are, there's a significantly cleaner way of handling loading your depenencies anyway.

License

(The MIT License)

Copyright (c) 2013-2014 Stephen Mathieson <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

node-obfuscator's People

Contributors

adrai avatar benweet avatar jamydev avatar sgorshechnikov avatar stephenmathieson avatar zzmp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-obfuscator's Issues

mean stack obfuscation error

Hi,

Thanks for this great project. Having problem when obfuscating the mean stack. To test it I created a simple script:

mkdir try
cd try
wget https://github.com/meanjs/mean/zipball/master
unzip master
cd meanjs-mean-*
npm install
npm install grunt-obfuscator --save-dev

echo "module.exports = function (grunt) {
  grunt.loadNpmTasks('grunt-obfuscator');

  grunt.initConfig({
    obfuscator: {
      files: [
        'server.js', 'config/**/*.js', 'app/**/*.js'
      ]   ,
      entry: 'server.js',
      out: 'obfuscated.js',
      strings: true,
      root: __dirname
    }
  });

  grunt.registerTask('default', ['obfuscator']);
};
" >> obfuscate_gruntfile.js

grunt --verbose --gruntfile obfuscate_gruntfile.js

node obfuscated.js

The error is:

/home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:1
e\x63\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x2e\x6a\x73"]=c.extensions["\x2e\x6a
                                                                    ^
TypeError: Cannot read property '.js' of undefined
    at a.exports (/home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:1:20015)
    at Object.<anonymous> (/home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:1:1243)
    at c (/home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:1:424)
    at /home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:2:19184
    at Object.<anonymous> (/home/bor/tmp/try/meanjs-mean-2c319c5/obfuscated.js:2:19234)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Comment at the end of the line of a js file causes an error

I've tried running the app with a file which generates source maps, but it seems like uglifier fails when there is a comment on the last line of the js file. I get this error

{ [Error: Unexpected token: eof (undefined)]
  pos: 3258,
  col: 20,
  line: 117,
  filename: null,
  source: '...' }

Error
    at new JS_Parse_Error (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:196:18)
    at js_error (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:204:11)
    at croak (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:680:9)
    at token_error (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:688:9)
    at unexpected (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:694:9)
    at block_ (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:1006:28)
    at ctor.body (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:980:25)
    at function_ (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:985:15)
    at expr_atom (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:1193:24)
    at maybe_unary (/Users/someone/node_modules/obfuscator/node_modules/uglify-js/lib/parse.js:1363:19)

where the file to obfuscate looks something like this

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
// ...
var SomeClass = (function (_super) {
    __extends(SomeClass, _super);
    function SomeClass() {
        _super.call(this, true);
    }
    return SomeClass;
})(MessageDispatcher);
module.exports = SomeClass;
//# sourceMappingURL=SomeClass.js.map

(generated from the Typescript compiler, if you are interested)

If I remove the last line, it works fine. I'm guessing the uglifier parser doesn't expect comments at the end of the file.

Uncaught ReferenceError: require is not defined

When using this npm package, I keep getting the following error:

Uncaught ReferenceError: require is not defined

Im using it in an angular project and after building and running the application I got that error. Is there a way to fix this? Or am I missing something ?

Thank you for the help!

backlash and vertical tab characters in string were not correctly obfuscated

On this version of obfuscator:

├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   ├── [email protected]
│   ├─┬ [email protected]
│   │ └── [email protected]
│   ├── [email protected]
│   └─┬ [email protected]
│     ├── [email protected]
│     ├─┬ [email protected]
│     │ └── [email protected]
│     ├── [email protected]
│     └── [email protected]
  • a backslash character is not correctly obfuscated (with the options.strings set true): both '\\' and '\x5c' get obfuscated into "\underfined".
  • a vertical tab specified as '\v' or ``\x0b'gets obfuscated into"\xb"`.

In both cases I got a fatal error from node when executing the obfuscated codes of some large production code base as shown below. However I could not reproduce the same fatal error when testing with a simple test program. In both programs, the behaviors are incorrect.

SyntaxError: Unexpected token ILLEGAL
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:413:25)
    at Object.Module._extensions..js (module.js:452:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:475:10)
    at startup (node.js:117:18)
    at node.js:951:3

The problem lies in /lib/utils.js:exports.hex() -

    if (map[char]) {
      result += map[char];
    } else if ('\\' == char) {
      result += '\\' + str[++i];
    } else {
      result += '\\x' + str.charCodeAt(i).toString(16);
    }

In the case of a single character of escaped backlash, it will cause str[++i] producing "undefined". For the case of '\v', the leading zero is perhaps dropped by the charCodeAt(i).

Suggested fix: expanding the map object in /lib/utils.js to include all the official JavaScript special characters as defined in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types:

/**
 * Escape map.
 */

var map = {
  '\b': '\\b',
  '\f': '\\f',
  '\n': '\\n',
  '\r': '\\r',
  '\t': '\\t',
  '\v': '\\v',
  '\\': '\\\\',
  '\0': '\\0'.
  '\"': '\\"',
  "\'": "\\'"
};

ecmascript 6

any way of obfuscating generators and other ecma6 stuff? I know it it depends on uglifyjs, but maybe you already know how to do it :) thanks

Issues with obfuscated regex matches

In my code, I do a regex match for a string like this.

str.match('^\\d+$')

This gets obfuscated to -

str.match("\x5e\d\x2b\x24")

This doesn't seem to work though, as seen below -

> str="12345678901234567890";
'12345678901234567890'
> str.match('^\\d+$')
[ '12345678901234567890',
  index: 0,
  input: '12345678901234567890' ]
> str.match("\x5e\d\x2b\x24")
null

Error after compilation

Thank you for this great script. It does the job very nice, changed my variable contents to hex code and I kinda like it, only to give error when I tried to run my script.

After the successful compilation, when I use my compiled script on the browser, it give me lots of unexpected errors like ". (" etc.
Isn't there any way to get rid of those errors. It is useless if I get unexpected errors in my script with the compiled script. So for now I've switched back to uglify plugin of grunt.

Any suggestions???

N.B. I was using my client side script to obfuscate, and its a huge chunk of file, more than 300kb without minification.

`__dirname` hack

It is not an issue, frankly, but more like some kind of notes in case if some others happen to stumble upon this humble note and, well, in need of something like this.

In my case, a project that "requires obfuscation" (well, talk about those cases), it has quite some lines of code that requires doing something on __dirname like path.resolve(__dirname, '..', 'package.json') or so. They won't work as they are concatenated, obviously, and placed at the root of the directory.

Therefore, I have hacked something like the following to "kind of" conserve the __dirname for the module within. It is a rough hack and works for me here, but I am pretty sure it is not for everyone.

obfuscator.register = function (root, file, cb) {
  var filename = dotslash(path.relative(root, file));

  fs.readFile(file, 'utf-8', function (err, data) {
    if (err) {
      return cb(err);
    }

    var code =
      'require.register("' + filename + '",' + 'function (module, exports, require) {' +
        'var ___dirname = __dirname + "/' + filename.substr(2, filename.lastIndexOf('/') - 2) + '";' +
        (rJSON.test(file)
          ? ('module.exports = ' + data + ';')
          : data.replace(/__dirname/g, '___dirname'))
      + '});';
    return cb(null, code);
  });
};

The __dirname gets uglified nicely so it would work within. Be noted that in my case I have only tested with cases where './' is the defacto root - it probably won't work if it is not the case.

Again it is a horrible, horrible, kind of hack. Not sure how useful it can be for any of you who are reading this, but, well, take it if you need something like that. YMMV, though.

Cannot run the obfuscator task: Invalide root directory

I use the following config for my obfuscator task:

obfuscator: {
     files: [
      'app.js',
      'config/*.js',
      'lib/*.js'
     ],
     entry: 'app.js',
     out: 'obfuscated.js',
     strings: true
   }

but I got the following error when running

grunt obfustate

Running "obfuscator" task
Warning: Invalid root directory Use --force to continue.

Any idea of this error message ?

Support source maps

It would be REALLY cool if node-obfuscator could generate source maps that link the obfuscated JavaScript code back to the appropriate source file/line/column, etc. for debugging purposes.

From what I understand, you could pass a source map option to node-obfuscator to eventually be passed along to uglifyjs; however, this source map would be for the concatenated JavaScript, not for the original source. With a little bit of work, it might be possible to map the uglifyjs source map back to the original source code.

Thoughts on this?

Running tests against obfuscated code

I was wondering how you would approach running tests against the obfuscated code.

For instance, while all my tests pass prior to obfuscation, after doing so it's possible I broke something. Using __dirname would point to a potentially incorrect path.

To avoid these headaches I was attempting to run all of my unit tests against the obfuscated code, but that doesn't work due to the require paths being completely wrong in the unit tests. I was wondering if you could give me some direction at solving this.

Because the single entry point is exported, it seems impossible to get access to the require'd files from outside of the file.

Can't require packages

Hi,

when obfuscating my script which works pretty well, this is what happens:

fusl@thinkbook:~/nodecast> ./transcoder2.js < transcoder.json

/home/fusl/nodecast/transcoder2.js:2
a("\x2e\x2f"+c.basename(b));if(d=c.resolve(b),e=c.cache[d],!e)throw Error('fai
                                                                    ^
Error: failed to require "./functions.js"
    at Error (<anonymous>)
    at c (/home/fusl/nodecast/transcoder2.js:2:160)
    at b (/home/fusl/nodecast/transcoder2.js:2:735)
    at Object.<anonymous> (/home/fusl/nodecast/transcoder2.js:2:986)
    at c (/home/fusl/nodecast/transcoder2.js:2:229)
    at /home/fusl/nodecast/transcoder2.js:2:15340
    at Object.<anonymous> (/home/fusl/nodecast/transcoder2.js:2:15406)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)

And this is what it should look like:

fusl@thinkbook:~/nodecast> ./transcoder.js < transcoder.json
27 Nov 13:13:26 - Spawning mount(/main-192.mp3)
27 Nov 13:13:26 - Spawning mount(/main-192.mp3)
27 Nov 13:13:26 - Spawning mount(/main-128.mp3)
27 Nov 13:13:26 - Spawning mount(/main-128.mp3)
27 Nov 13:13:26 - Spawning mount(/main-128.aac)
27 Nov 13:13:26 - Spawning mount(/main-128.aac)
27 Nov 13:13:26 - Spawning mount(/main-64.aac)
27 Nov 13:13:26 - Spawning mount(/main-64.aac)
27 Nov 13:13:26 - Spawning source(dj)
27 Nov 13:13:26 - Spawning source(playlist)
27 Nov 13:13:26 - Spawning source(silence)

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EADDRINUSE
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1039:14)
    at listen (net.js:1061:10)
    at net.js:1135:9
    at dns.js:72:18
    at process._tickCallback (node.js:415:13)

// Edit:
I compiled with

obfuscator --out transcoder3.js --strings --entry transcoder2.js ./transcoder2.js

export a function with static methods, not an object

this is ugly:

var obfuscator = require('obfuscator')

var opts = obfuscator.options(...)

obfuscator.obfuscator(..., function () { ... })

and should just be:

var obfuscator = require('obfuscator')

var opts = obfuscator.options(...)

obfuscator(..., function () { ... })

Request for an option to output the concatenated source so uglifyjs warning can be taken care of more easily

Not a high priority but a nicety to have an option to output the concatenated source so uglifyjs warning can be taken care of more easily, say, in utils.js,

exports.uglify = function (js, opts, cb) {
...
    return cb(null,  stream.toString(), js);
...
}

with the source output, the line number from the uglifyjs warning can be easily found:

WARN: Non-strict equality against boolean: != true [null:3470,6]

BTW, obfuscator is a great tool!

Help obfuscating my node.js project

I have directory structure something like below.
.\server.js
.\logic\ a.js
.\logic\ b.js

I am trying to obfuscate the entire project before deploying it. Using this tool I could obfuscate but get errors executing it

obfuscator --entry server.js ./server.js ./logic/a.js ./logic/b.js -o ugly.js

Could you please help perfecting this command so that my application can run?
Thanks in advace

TypeError: Cannot set property '.jse' of undefined

Hi,

I was trying to obfuscate a code with

    require.extensions['.jse] = function(module, filename) {
        var content = fs.readFileSync(filename, 'utf8');
        return module._compile(content, filename);
    };

But got the following error when the output file is executed
TypeError: Cannot set property '.jse' of undefined

How to fix this? Any clue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.