65

I want to use node.js in my next project, but my boss does not like that our competitors can read the source code.

Is there a way to protect the JavaScript code?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Van Coding
  • 24,244
  • 24
  • 88
  • 132

14 Answers14

73

You could accomplish this with a NativeExtension for node

You'd have a boostrap.js file that adds a extension handler for .jse files

// register extension
require.extensions[".jse"] = function (m) {
 m.exports = MyNativeExtension.decrypt(fs.readFileSync(m.filename));
};

require("YourCode.jse");

YourCode.jse would be the encrypted version of your source code (the key for decryption wouldn't be anywhere in plain-text because the decryption process takes place in the native extension).

Now you have your NativeExtensions decrypt function transform the source back to javascript. Just have your build process create encrypted .jse versions of all your files and release those to your customers. They'd also need the native extension but now you've made it a little harder to modify your code without too much effort. You can even make the native extension call home and check license information to help prevent piracy (keep in mind this won't stop piracy, there's no solution for that).

Salketer
  • 14,263
  • 2
  • 30
  • 58
Christopher Tarquini
  • 11,176
  • 16
  • 55
  • 73
  • 1
    No problem, let me know how it goes, I'm planning on using this method on one my projects as well. Someone should develop a library for this sort of thing – Christopher Tarquini Feb 07 '12 at 15:29
  • Keep in mind that the native extension also has to use v8 to convert the source into a javascript object for node to use. You can also use `m._compile(MyNativeExtensions.decrypt(..))` but then all anyone has to do change your source is change `m._compile` to `console.log` – Christopher Tarquini Feb 07 '12 at 15:44
  • 56
    This is not secure. It doesn't matter that the key is hidden in the binary module. Once the client decrypts and loads your module, they can simply call console.log(yourmodule.yourmethod.toString()) and print out your source code. – dlongley Jun 07 '12 at 03:49
  • ^ Well he only needs to make his boss happy ;). Obviously there's no way to solve this problem in a language like javascript. The "most secure" way I can think of would be ustom node-binary bundled with your scripts that only runs them (load them in RAM perhaps? Which might require modifying the `require` function to check the apps resources before checking for files). – Christopher Tarquini Jun 13 '12 at 12:33
  • Isn't there any open source library/extension/project for this? – Mark Aug 15 '12 at 01:42
  • You don't need a custom native extension for encryption/decryption, this makes deployments convoluted. I would suggest using the native to node decryption combined with a min/obfuscation option like closure, or uglify. If your original source is coffeescript, that's another layer... – Tracker1 Dec 31 '12 at 20:27
  • Quick note: @dlongley Don't quote me on this but I believe if you have your decryption method written in a native node extension you can prevent `Function.prototype.toString` from working on the code you compile and add to the runtime in C++ land. – Christopher Tarquini Jan 10 '14 at 19:28
  • @Tracker1 Anything in JS land will be trivially defeated by something like JSBeautifier. Using node's native decryption is a no-go as well because you can just change it to print the decrypted source instead of evaling it. Really when it comes down to it you're not going to get very far with code protection with node, especially since V8 uses the source code at runtime and needs the AST in memory – Christopher Tarquini Jan 10 '14 at 19:30
  • 18
    @ChrisT It isn't always about practicalities.. generally speaking, running through uglify before distribution is enough, and even with a JS beautifier, you won't get comments or the original variable names, which really makes it harder to reverse engineer something. --- Even then, anyone that could get that far, could probably have written it themselves. – Tracker1 Jan 15 '14 at 00:53
  • @Tracker1 Right but this doesn't answer the question. Ideally you'd never have to do this but he wanted a way to encrypt not obfuscate – Christopher Tarquini May 03 '14 at 20:55
  • 2
    I've wrapped @Chris T idea into a working [github repo](https://github.com/pawelsledzikowski/jse-decryptor) if anyone is interested. However, be aware that this is still a locking the front door and leaving the key under the outdoor rug - looks like it's locked but actually not really. – Pawel Sledzikowski Nov 06 '14 at 00:49
  • 1
    @dlongley Won't storing your function source inside a closure and returning a publicly accessible method that calls the internal private method in the closure prevent the actual code from being accessible by simply using toString() ? – Johny Jose Jan 26 '15 at 11:27
  • @JohnyJose, hmm, yeah, that might prevent toString() access at some level. You may still be able to print it out another way, though, I haven't put a lot of thought into it. The right solution is still licensing, but that's an interesting idea. – dlongley Jan 26 '15 at 16:49
  • @PawelSledzikowski little bit late but your code works like harm. I did some modifications in order to work with nan. Thx a lot for your project! – kostas ch. Jun 10 '18 at 11:37
18

Just include a license agreement and give them the source code. They might want to customize it anyway.

Mike Blandford
  • 3,952
  • 4
  • 29
  • 32
  • 7
    For me, this is a great idea, but for my boss, this is too dangerous. If the world only could be less complicated... – Van Coding May 10 '11 at 15:20
  • 6
    This is the right answer, IMO. There is no fool-proof way to prevent the client from doing what you fear. If you're interested in making it more difficult you can try some of the obfuscation solutions proposed in this thread or look at v8's heap snapshot feature. However, the license agreement is vital. -- Just realized this is '11 not '12, oh well! Hope it worked out :) – dlongley Jun 07 '12 at 03:58
11

As I have just completed a huge pure Nodejs project in 80+ files I had the same problem as OP. I needed at least a minimal protection for my hard work, but it seems this very basic need had not been covered by the NPMjs OS community. Add salt to injury the JXCore package encryption system was cracked last week in a few hours so back to obfuscation...

So I created the complete solution, that handles file merging, uglifying. You have the option of leaving out specified files/folders as well from merging. These files are then copied to the new output location of the merged file and references to them are rewritten auto.

NPMjs link of node-uglifier

Github repo of of node-uglifier

PS: I would be glad if people would contribute to make it even better. This is a war between thieves and hard working coders like yourself. Lets join our forces, increase the pain of reverse engineering!

user2667976
  • 157
  • 2
  • 6
  • 1
    I know it's an old post, but I still looking for a solution to protect my code against piracy. Haven't you find a more reliable solution to this purpose?! Tnx – eArmin Jun 11 '18 at 19:48
  • is it possible to keep few keyword as it is without obfuscation? – mahesh Jul 08 '18 at 09:38
  • I tried using this but it's not able to import the node modules. – chetan Feb 14 '22 at 15:50
9

To be very clear, client-side Javascript (as downloaded from a remote server into a standard web browser) cannot be protected from viewing and/or modification no matter how you obfuscate it since reconstruction ("de-obfuscation") of the original source is technically trivial. (Javascript obfuscation is simply another example of the widely used security misnomer "security through obscurity".)

If you wish to use Javascript and Node.js to provide a protected "product" (which in this context is an application or service requiring installation on a server your company does not control), you cannot secure it either as the only option available to you (obfuscation) provides no such protection.

It should be noted that even if your product is provided as a binary executable that is no guarantee you can protect the intellectual property it contains as any binary can be decompiled into an understandable format. In this case, we enjoy some level of security based on the excessive resources (time/expertise) required to convert low-level machine code (as provided by decompilation) into the higher-level logic constructs used by modern programming languages. (This from one who once decompiled CP/M into an understanding of its internal design by hand. ;)

All however is not lost: if we assume that one can protect intellectual property programmatically (the jury is still out on this one), there is a way to provide a Node.js-based product in a secure fashion, but it is not for the technically unadventurous as it would require substantial refactoring of the Node.js source code (to add support for cryptographically secure libraries and remove--or otherwise protect--object reflection for your proprietary libraries.)

Rob Raisch
  • 17,040
  • 4
  • 48
  • 58
  • 2
    While this is true, it should be said that if you can reverse-engineer a product written with say coffeescript using requirejs, and then compiled into a single js, then run through closure... from that encrypted into a custom extension, with the exposing module loading it via a stub... you probably didn't *NEED* to reverse engineer it to replicate any given functionality. – Tracker1 Dec 31 '12 at 20:34
5

JXcore (node.js 0.11.X distro) has its own JX packaging feature that secure the source code and assets. You can even select whether that particular package can be used from other applications or not. (standalone OR library)

Let's say you have many JS etc. files and the entry point to your module is something like;

exports.doThis = function() { ...... };

if you simply call the method below and compile it to JX package, the source code will be safe.

jxcore.utils.hideMethod(exports.doThis);

this is (method hiding) would only required for the entry file since all the other sub JS files not reachable from the calling application.

You need JXcore to run JX packages.

More information is available from JXcore

Joel
  • 678
  • 8
  • 17
Nuray Altin
  • 1,294
  • 12
  • 19
  • 2
    Please note: jxcore does not protect the source (at least, anymore): https://github.com/jxcore/jxcore/issues/857#event-579583412 – Ashwin Mar 07 '16 at 09:01
5

You can use EncloseJS - compiler for node.js projects. It really compiles JavaScript to native code, and your sources are not included to binary.

Igor Klopov
  • 279
  • 3
  • 5
  • 4
    The license of EncloseJS doesn't allow commercial use. – aleung Aug 20 '15 at 09:41
  • 2
    The very first feature on the web site: "Make a commercial version of your application without sources". Also, it's a paid/subscription product, so it seems that his intention is commercial use. – Blisterpeanuts Jan 04 '16 at 14:50
  • 1
    Dear users of EncloseJS. I highly encourage you to switch to https://github.com/zeit/pkg. This a rewritten successor of EncloseJS. It is open source, and all improvements will go there – Mladen Oršolić Apr 20 '18 at 13:21
  • 3
    PKG doesn't appear to hide anything, you can open the binary in VIM and see all the source. just my experience. – Jason Jul 17 '18 at 15:23
  • @Jason This is solved here: https://github.com/vercel/pkg/issues/190. Tldr: Any chance there is `"license": "ISC"` in package.json? Remove that to get rid of sources. – Markus Pscheidt Feb 13 '21 at 16:16
4

Package your core logic into modules.. these modules can be built then run through Google's closure. You could even be able to do this as a Grunt task as part of your build process.

It's an old question but worth pointing out. Note: nothing you do will truly hide your code, but neither will anything shipped via .Net (C#) or Java for that matter. In general, simply using a tool like uglify, or closure should be enough of an obfuscation point. By being modular and using closure you can actually do a lot of optimizations that otherwise would be difficult.

Tracker1
  • 19,103
  • 12
  • 80
  • 106
4

Server side javascript code is completely closed source. No-one can read it.

Client side javascript code is completely open source. Everyone can read it.

For the latter you can do nothing but the same applies for RoR, ASP.NET, PHP, etc.

The actual server code is closed unless you publicly make it available.

If your making a library and trying to sell it as 3rd party source then it's open and can be stolen. Of course you can sue them for copyright breach.

There are various big companies like extjs which sell libraries which could be stolen that's why what they actually sell you is the code and a support service.

Most commercial projects build on node are services.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 7
    We want to use it in a product. When a competitor installs this product, he will see the sourcecode. – Van Coding May 10 '11 at 14:09
  • This is why all node.js commercial projects are services and not products. You can obfuscate your source with [UglifyJS](https://github.com/mishoo/UglifyJS). – Giacomo May 10 '11 at 14:29
  • @FlashFan so your creating a library and selling it. It's open source. – Raynos May 10 '11 at 14:40
  • it´ll be a service with a webinterface. The webinterface will be realtime, so node.js would be really well suited. But yes, it´ll be a commercial product. I can´t change this ;) – Van Coding May 10 '11 at 14:49
  • @FlashFan if your not physically giving your server side source code to clients then your safe. They can see the client side code and they've always been able to do that. That's a fault of web programming. – Raynos May 10 '11 at 15:06
  • @Raynos: The problem is: we do not host this service. Our customers will install it on their servers and run it. It´ll be very easy for our competitors to get the code. They´ll simply download the service and install it. – Van Coding May 10 '11 at 15:13
  • 3
    @FlashFan if they breach your _copyright_ or if they use your code without _permission_ then you can _sue_ them. Welcome to piracy. – Raynos May 10 '11 at 15:27
  • You´re so right ;) Maybe I´ll have to talk with my boss again... It would be worth it! Node.js is so much easier to use and makes 100-times more fun :P – Van Coding May 10 '11 at 15:32
  • @FlashFan 1) as Ryanos point out, server side node.js's javascript code is COMPLETELY closed, even your default html files in /view . only the client side css & js are accessible by public (in /public folder). 2) client side js is open to public, even crypted. But there are techniques (e.g. on demand loading) to make it harder for ppl to steal your client side js. 3) to protect your node.js code, u can't hide 100%. However, there still some possible way to hide partial node.js code. – murvinlai May 10 '11 at 21:28
  • @FlashFah as stated above in 3) there may be a way to do that. First, I haven't done it and it is just a concept. By how data is stored in MongoDB (yes.. mongo now), and how data is returned to Node.js, you can actually store function in mongodb. So, the idea is, step a), only registered client has the login/password to connect to mongo. step b) some core functions are stored in db (u may encrypt it if you wish). step c) when nodejs app runs, it authenticates and connect to mongo & get the functions. Of course, it is up to you who to give access. – murvinlai May 10 '11 at 21:33
  • @murvinlai it's worth noting that you can simply disable authentication in the mongo service in order to access the underlying data... if you control the hardware, you have access. – Tracker1 Dec 31 '12 at 20:37
  • @murvinlai - this line "Our customers will install it on their servers and run it. It´ll be very easy for our competitors to get the code", doesnt even talk about it server side js as being closed, the clients actually have access to the server code. unless if the van coding would implement something like this http://en.wikipedia.org/wiki/Always-on_DRM then the source code is always accessible, there's a reason why some games require internet for login – ianace Jul 30 '13 at 03:05
3

you can use packer for nodejs for obfuscate your script...

oshimin
  • 31
  • 1
1

Anyone tried nexe or pkg ?

These seems like a good option. A command-line utility that compiles your Node.js application into a single executable file.

Ligo George
  • 819
  • 2
  • 9
  • 21
1

Check this article.

I will show you how to “truly” compile Node.js (JavaScript) code to V8 Bytecode. This allows you to hide or protect your source code in a better way than obfuscation or other not-very-efficient tricks (like encrypting your code using a secret key, which will be embedded in your app binaries, that’s why I said “truly” above).

So, using bytenode tool, you can distribute a binary version .jsc of your JavaScript files. You can also bundle all your .js files using Browserify, then compile that single file into .jsc.

Check bytenode repository on Github.

Pang
  • 9,564
  • 146
  • 81
  • 122
ho raj
  • 83
  • 1
  • 8
1

There is no way you can be absolutely sure that nobody will be able to read your code. You could use obfuscation or minification, which can make it significantly harder to decode your code, though. One example of an obfuscator/minifier is Google's Closure Compiler for JavaScript.

jwueller
  • 30,582
  • 4
  • 66
  • 70
0

Pkg comes in handy.

To be sure sources aren't included in the generated output file, verify that package.json doesn't specify a license (such as "license": "ISC") that would force inclusion of sources. See https://github.com/vercel/pkg/issues/190 for details.

Markus Pscheidt
  • 6,853
  • 5
  • 55
  • 76
-4

I have an idea. Protect a cpp or java application instead of js.

  1. Wrap your code in an encryption format, and compile it as a utf-8 file resource.
  2. Use your cpp or java application to upload the entire file to a linux pc or arm computer, make sure you have a strong password or close ssh port or disable the video port and browse the linux pc only by web.
  3. There is a cpp program to decrypt the file in the linux pc.
  4. Develop a webserver to controll your linux pc.

So this is much like a black box, the clients can do nothing to your code.

Praveen Vinny
  • 2,372
  • 6
  • 32
  • 40
张铁男
  • 99
  • 5
  • It's not secure at all. C++ apps can be easily reverse-engineered using IDA Pro (with the hex rays plugin) or Ghidra or Cutter and java apps can be reverse-engineered using JDAX or JD-GUI – Erfan Azhdari Mar 13 '20 at 01:36