By TheFlash


2012-02-23 12:31:40 8 Comments

What: Can NodeJS apps be distributed as binary? ie. you compile the .js app via V8 into its native binary, and distribute the binary to clients? (if you had total access to the NodeJS server)... or is minifying the code all you can do?

Why: We build serverside applications in NodeJS for clients, that have often to be hosted on the client's servers. Distributing source code means clients can easily steal our solution and stop paying licensing fees. This opens up the possibility of easy reverse-engineering or reuse of our apps without our awareness.

6 comments

@adnan kamili 2019-08-21 13:17:49

We have been using pkg to create binary versions of our Node.js app before distribution.

https://github.com/zeit/pkg

In order to add license key checking we use Cryptlex:

https://docs.cryptlex.com/node-locked-licenses/using-lexactivator/using-lexactivator-with-node.js

@TheFlash 2015-03-16 18:10:13

EncloseJS.

You get a fully functional binary without sources.

JavaScript code is transformed into native code at compile-time using V8 internal compiler. Hence, your sources are not required to execute the binary, and they are not packaged.

Perfectly optimized native code can be generated only at run-time based on the client's machine. Without that info EncloseJS can generate only "unoptimized" code. It runs about 2x slower than NodeJS.

Also, node.js runtime code is put inside the executable (along with your code) to support node API for your application at run-time.

Use cases:

  • Make a commercial version of your application without sources.
  • Make a demo/evaluation/trial version of your app without sources.
  • Make some kind of self-extracting archive or installer.
  • Make a closed source GUI application using node-thrust.
  • No need to install node and npm to deploy the compiled application.
  • No need to download hundreds of files via npm install to deploy your application. Deploy it as a single independent file.
  • Put your assets inside the executable to make it even more portable. Test your app against new node version without installing it.

@aleung 2015-08-20 09:34:17

The license of EncloseJS doesn't allow commercial use.

@Alexis Paques 2015-09-09 16:57:23

Sorry, but it does, you just have to contact the dev. Free for non commercial use does not mean you cannot use it. It means you will have to pay to use it.

@Sergey Yarotskiy 2017-12-14 15:00:42

EncloseJS is deprecated. It's successor pkg is open source and distributed under MIT license. github.com/zeit/pkg

@Igor Klopov 2015-02-16 17:46:42

V8 generates native machine code internally and executes it. Look here: https://github.com/v8/v8-git-mirror/blob/master/src/compiler.cc#L1178 . This feature is used in EncloseJS. EncloseJS parses the sources of your node.js project, bundles dependencies, and makes an executable binary. The sources are not included in the binary - only compiled machine code.

@Alexis Paques 2015-09-09 16:58:43

It is only the lazy compiled native code ! (2 times slower than the optimized one they say)

@kvz 2013-09-22 13:54:01

I'm currently investigating the same thing and am looking at nexe which claims to be able to "create a single executable out of your node.js apps".

Can't tell you if it's any good just yet, but thought it'd be worth to share already.

@Félix Brunet 2019-02-21 16:56:11

Nexe permit to create a stand-alone executable, but do not obfuscate the code at all. you can easily retrieve the javascript code at the end of the (huge) binary file.

@Thiago de Arruda 2012-09-28 12:40:53

Yes it is possible, use this branch(based on 0.8.18) and any js code you put in 'deps/v8/src/extra-snapshot.js' will be ahead-of-time compiled to machine code and embedded in v8 as part of the normal builtin object initialization. You will need to build nodejs for each platform you intend to deploy your product.

The snapshotted code runs very early in the v8 initialization and you cannot access builtin objects in the 'module body'. What you can do is put all your code inside a global initialization function to be called later. Ex:

// 'this' points to the same as the object referenced by 
// 'global' in normal nodejs code.
// at this point it has nothing defined in it, so in order to use
// global objects a reference to it is needed.
var global = this;
global.initialize = function() {
  // You have to define all global objects you use in your code here;
  var Array = global.Array;
  var RegExp = global.RegExp;
  var Date = global.Date;
  // See ECMAScript v5 standard global objects for more
  // Also define nodejs global objects:
  var console = global.console;
  var process = global.process;
  // Your code goes embedded here
};

Also, this assumes your entire code is defined in a single file, so if your project uses nodejs module system(require) you need to write a script that will combine all your files in one and wrap each file in a closure that will trick your code into thinking it is a normal nodejs module. Probably each module closure would expose a require function, and this function would have to decide when to delegate to the standard 'global.require' or return exports from your other embedded modules. See how javascript module systems are implemented for ideas(requirejs is a good example).

This will make your code harder to debug since you wont see stack traces for native code.

UPDATE:

Even using v8 snapshots the code gets embedded in the node.js binary because v8 prefers lazy compilation. See this for more information.

@James 2013-02-27 06:20:25

Thank you this is very useful I must try this.

@Raynos 2012-02-23 20:27:23

Yes you can create a binary format. V8 allows you to pre-compile JavaScript. Note that this might have a bunch of weird side-effects on assumptions made by node core.

Distributing source code means clients can easily steal our solution and stop paying licensing fees.

Just because you distribute the binary doesn't protect you againsts theft. They can still steal the binary code or disassemble it. This is protection through obscurity which is no protection at all.

It's better to give them a thin client app that talks to your server and keep your server code secure by not giving it away.

@user4815162342 2013-02-28 14:23:44

@James Andino: But, even if you could compile the code, what's preventing someone from taking the executable and data files and installing them on another machine? Compiling code isn't analogous to locking a car. Compiling is a performance and packaging measure, not a security measure.

@James 2013-02-28 14:33:55

well my only defense to that logic is name calling.

@Raynos 2013-02-28 18:07:48

These things are generally a losing race. However many resources you pump into "securing this" the other side will have more resources. You should simply not worry about this and ensure your business isn't dependent on the magic sauce in your code but on actual non-code value your company produces.

@Spoike 2013-07-23 09:20:15

+1 for the suggestion of thin client app. Putting critical business logic server-side is more "secure" than distributing executable with the same business logic. Disassembling binaries (and patching them for nefarious purposes) is very easy to do with current tools at today's date.

@kumarharsh 2014-07-31 14:30:40

The way Nodejs has been evolving, the best way would definitely be a thin client. I agree with @JamesAndino on the analogy though :P I mean, by obfuscating, the developer is just setting the bar higher, so there will be lesser people who can do the reverse engineering. Although, with nodejs, it would not be worth the effort to take so much headache. Try pitching a "thin client" approach to your client.

@Dzenly 2015-10-22 05:05:05

Sometimes clients are so secure as prevent any internet access. I.e. there are use cases when your business logic must be on client's server. So the problem of securing node.js server code is quite actual.

@mwag 2016-06-30 14:26:00

Agree w @Dzenly. In addition, "protection through obscurity which is no protection at all" is false. as kumar_harsh points out, it merely raises the bar, BUT just because the bar is not insurmountable doesn't mean it doesn't provide value-- otherwise you could say the same of any security system. This is especially true for enterprise products. Also, clients that require high security are more likely to have strong controls that make it difficult, possibly a fireable offense, for employees to reverse engineer their vendors' products.

Related Questions

Sponsored Content

19 Answered Questions

[SOLVED] Is there a way to get version from package.json in nodejs code?

47 Answered Questions

[SOLVED] How can I update NodeJS and NPM to the next versions?

39 Answered Questions

[SOLVED] How to fix Error: listen EADDRINUSE while using nodejs?

  • 2012-03-27 22:00:59
  • Danny Fox
  • 652176 View
  • 475 Score
  • 39 Answer
  • Tags:   javascript node.js

39 Answered Questions

[SOLVED] How do I debug Node.js applications?

14 Answered Questions

[SOLVED] Secure hash and salt for PHP passwords

1 Answered Questions

[SOLVED] Security of Text Hashing with NodeJS Server

Sponsored Content