Hide source code possibility #269

Closed
darky opened this Issue Dec 18, 2012 · 71 comments

Projects

None yet
@darky
darky commented Dec 18, 2012

I mean about executable container, which not allow to show source code.
Not offer obfuscation

@Mithgol
Contributor
Mithgol commented Dec 18, 2012

The users will have that container and the open source decoder (which is node-webkit) and the key (if there is a key), because node-webkit needs to open that container somehow (in order to execute its contents).

How do you expect the container's contents to remain concealed then?

@aesposit

@Mithgol
My suggestion is to add the capability to compile the js&css files in the exe executable as embedded resources and then use them internally as custom NWURL.
Something similar to this : http://www.developer.nokia.com/Community/Wiki/How_to_Embed_Resources_in_the_Application_Executable

@graphnode

My suggestion is to add the capability to compile the js&css files in the exe executable as embedded resources and then use them internally as custom NWURL.

Aren't executable resources even easier to read than just appending a zip file to node-webkit like it happens in the Windows deploy?

@aesposit

@graphnode
the problem is that the zip file is extracted in the temp dir and so easily readable.
BTW if you have hackers cracking your apps probably nothing can stop them.
What I would like to achieve is making hard (not impossible) to see my code.
I am trying to use this process in Windows:

  1. Encrypt your js resources with a unique desktop key (I use node-ffi with a HW HD serial number dll)
  2. Embed those resources in the exe (normal users don't know that)
  3. Launch the exe and it internally in memory decrypt/loads the resources in the nw browser/node context

Any suggestion is welcome

@darky
darky commented Dec 19, 2012

I front-end dev and don't want to show my source (HTML/CSS/JS) customers up to get money.
But they want to see state of project and I have next idea: to give customes special build of node-webkit (Windows) with next features:

  1. without toolbar, plugins, e. t. c. superfluous...
  2. open my server resource by https
  3. with special user-agent password, which checked by server

How to create this build:

  1. Build node-webkit master branch with features
  2. Use Visual Basic Script:
    CreateObject("Wscript.Shell").Run 'nw.exe --no-toolbar --url="https://my-server.herokuapp.com" --user-agent="lhMf4Tct78ro08r74hUTR88bJ258FI" '
    This script exported in exe with ExeScript for example
@rogerwang
Member

It should be possible to 'protect' the JS code with something based on v8 snapshot. We'll see this feature, but some contract is still suggested to protect your IP by law.

I can see a standalone tool to compile the code into v8 snapshot and the support in node-webkit to load them on start.

@nathanprobst

+1 for V8 snapshot support!

@robgrz
robgrz commented Jan 18, 2013

I understand that this would just be an annoyance for someone who is truly dedicated to getting your code/source or copying the program but it would be a major roadblock for many people.

It would be a big benefit for some of the applications we've been looking at using node-webkit for.

+1 for me

@rogerwang rogerwang closed this in 549e3a8 Feb 10, 2013
@rogerwang
Member

This feature was just released with 0.4.2.

@dubcanada

@rogerwang may I ask why it is limited to such a low amount? If it's based off V8 and using a heap snapshot should it not be limited to maximum heap snapshot size (256mb?)?

@rogerwang
Member

@dubcanada it's not a hard limit and can be fixed. The reason of the current limitation is that the objects or code has to be in the same page when deserializing.

@kevsmt
kevsmt commented Apr 8, 2013

We are looking to use node-webkit on a application, which by nature requires the codes (some) to be compiled, specially authentication of the product limitations, etc. From the wiki; "snapshot": "mysnapshot.bin" I assume only 1 bin file? can this be "snapshot": [ "a.bin", "b.bin" ] ? and what does ~30% slower mean, assuming, the compiled js only returns js code computations or the js also touches ui staff? and the compile js can also access nodejs.require?

@changtimwu

@rogerwang
Wow! Your commit is surprisingly short.

I'd like to add such a feature to off-the-shelf command line nodejs executive so I can launch node with snapshot this way.

node -snapshot snapshot.bin

According to your patch, it seems that V8::Initialize can accept a snapshot binary stream as parameter.

Besides loading the snapshot binary file and pass it to where nodejs initialize v8 instance, is there anything I need to take care?

@frankhale
Contributor

I'm thinking of migrating an intranet web application off the server and rewriting it for node-webkit. Given the baggage/limitations of nwsnapshot and the fact that anyone can read and or modify the code, how are you guys dealing with database authentication and such that requires usernames/passwords? I suppose doing something like this would also entail wrapping database access into a set of web services (and those would have to live on a server somewhere). Then the node-webkit app uses an API key assigned to each user or something to gain access.

@jtenner
jtenner commented Nov 20, 2013

@frankhale Hosting the solution on IIS for an intranet application on a domain was a perfect solution for me.

The login popup uses windows authentication and it worked perfectly.

I don't know what your solution needs to look like though.

@szwacz
szwacz commented Nov 20, 2013

@frankhale everything what is on client machine should be by definition considered untrusted. Making desktop application is nothing different in that matter, so all your sensitive data should stay on server.

@frankhale
Contributor

Windows authentication would certainly work and that is how it's currently
being done. There are actually no usernames/passwords floating around as
it's all client certificate based. I'm just trying to figure out the best
avenue of approach in order to move the traditional web application pieces
to a node-webkit client side application and how best to eliminate the need
for resources on the web server.. So I suppose a small authentication piece
on the webserver combined with web services for the database access would
be the simplest route. Additionally a mechanism for auto-updating the
client side code.

On Wed, Nov 20, 2013 at 1:46 PM, Jakub Szwacz notifications@github.comwrote:

@frankhale https://github.com/frankhale everything what is on client
machine should be by definition considered untrusted. Making desktop
application is nothing different in that matter, so all your sensitive data
should stay on server.


Reply to this email directly or view it on GitHubhttps://github.com/rogerwang/node-webkit/issues/269#issuecomment-28916542
.

@sesteel
sesteel commented Jan 9, 2014

I am wondering why the code runs slower. Could anybody offer an explanation?

@petejkim

This just provides a false sense of security. I could see the full source code using the Dev Tools after loading the snapshot.bin file.

We should just accept the fact that there's no reliable way of protecting JS source code. /cc @rogerwang

@rogerwang
Member

@petejkim there is a bug introduced in 0.8.0 which makes the source code exposed. Could you please try again with 0.7.4?

@rogerwang rogerwang reopened this Jan 22, 2014
@rogerwang rogerwang was assigned Jan 22, 2014
@darsain
darsain commented Jan 22, 2014

I am wondering why the code runs slower. Could anybody offer an explanation?

I'd also want to know. From my limited point of view, the snapshot should save loading time, as stuff doesn't need to be loaded individually and interpreted anymore, and run equally fast when loaded. But I have no idea how this actually works... so why is it 30% slower? And can anything be done about it?

I'm actually not that interested in hiding the source code, but instead this seems like a nice way how to put all stuff into one nice bin file and not have it scattered everywhere, or in need of unpacking into tmp folder and running from there. This looks like the nicest way how to package apps, no?

@CosmoMyzrailGorynych

The temp folder of node-webkit application may have own access policies which deny any access to the user, like Windows 8 Metro-applications do.
Also it would be cool if app.nw could be protected by password which is stored directly in app.nw.

EDIT
I'm gonna use such a snippet until any alternatives appear. It simply clears some scripts in temp folder as they're cached in webkit and thus not necessary to remain in fs.

temp_folder = process.cwd();
/* lots of code go there */
$(function () {
    if(temp_folder.indexOf('Temp/nw') != -1)
      fs.readdir(temp_folder, function (err, files) {
        if (err) console.log(err);
        else {
          for (i = 0; i < files.length; i ++) {
            if (files[i].indexOf('.js') || files[i].indexOf('.html') || files[i].indexOf('.css'))
            fs.unlink(temp_folder + '\\' + files[i], function () {
              void(0);
            })
          }
        }
      });
  });

Be careful: I occasionly killed all my code this way one day :[ Better create a copy before trying.

@rogerwang rogerwang closed this Feb 12, 2014
@rogerwang
Member

@darsain the code run slower because it's compiled with the slower compiler in v8. The other (faster) one needs runtime profiling data to do better optimizations.

@vohof
vohof commented Mar 10, 2014

I tried using enigma virtualbox for the hope of that but there are still nw* forders popping up on the temp folder. I'm hopeful there would be a solution to this soon ❤️ Well aside from the slower compiled code.

@rotatingJazz

@rogerwang Could we hope for a future patch to increase the size of the snapshot?

Why it matters

The reason this is a great feature to have is that it gives the developer head time to the market. I do not mind if someone eventually cracks my app, but I really do care if someone can quickly rip off most of the code and launch a competitive product in zero time 🐊

In b2c, licenses and law have no real practical importance for small companies. Not everyone has the size of MS and is able to sue across half the globe 😄

Compiling a healthy chunk of the app though is a practical mitigation strategy for that. Speed crucial functions, boilerplate/trivial/front-end code can always be left uncompiled by the developer and achieve the best of both worlds.

Crossing fingers 🎱 👯 😄

@denzp
denzp commented Mar 28, 2014

May be it resonable to implement native protocol handlers? Something like this:
package.json

{
  "scheme": {
    "code": "path/code_scheme.node",
    "resource": "path/resource_scheme.node"
  }
}

Native modules may be safer than JS to decrypt and unpack encrypted code or resources.
Only need is to expose API for creating protocol handler in C++

@simonhoss

Is it possible to load the snapshaot via JavaScript? This would be very helpful for loading plugins.

@darky
darky commented Jan 9, 2015
  1. Use Visual Basic Script:
    CreateObject("Wscript.Shell").Run 'nw.exe --no-toolbar --url="https://my-server.herokuapp.com" --user-> agent="lhMf4Tct78ro08r74hUTR88bJ258FI" '
    This script exported in exe with ExeScript for example

Now can use jxcore for this purpose

@rajiff
rajiff commented Feb 11, 2015

@rogerwang
Is .bin files readable (crackable) by users in any way?
Is it possible to have more than one .bin files in the app? @kevsmt too asked this above, not sure if that was answered, hence asking again

@shaynem
shaynem commented Feb 11, 2015

In my experience If you cat the bin file the info is still visible in
amongst the data using nwsnapshot which defeats the purpose.
On 11/02/2015 5:27 pm, "Basavaraj K N" notifications@github.com wrote:

@rogerwang https://github.com/rogerwang
Is .bin files readable (crackable) by users in any way?
Is it possible to have more than one .bin files in the app? @kevsmt
https://github.com/kevsmt too asked this above, not sure if that was
answered, hence asking again


Reply to this email directly or view it on GitHub
#269 (comment).

@hashseed

Maintainer and implementer of the serializer/deserializer in V8 here.

We've recently improved the serializer/deserializer a lot to support code caching and custom startup snapshot. Among others, the snapshot size issue has been fixed so that we can have arbitrary number of pages in the snapshot.

Using the code cache, JIT code compiled from a script can be serialized and later deserialized to bypass parsing/compiling. It's somwhere between 10x to 100x faster.

Using the custom startup snapshot, you can create a snapshot blob after running a user-specified script. When you pass in that snapshot blob in v8::Isolate::New, the serialized heap and context are restored.

What I'm curious about though is how you manage to hide the source code. V8 assumes that the source code is available in order to recompile (for debugging and when compiling for optimized code). Did you disable recompiling so that you can remove the source code?

@rogerwang
Member

@yangguo-chromium-org Glad to hear from you.

Starting from 0.12.0-rc1 NW uses v8 code cache to implement this feature, before that we use the startup snapshot. Thanks for your work to make this happen.

To answer your question: yes, we patched v8 to disable the recompilation. See nwjs/v8@67b65e0

https://github.com/nwjs/nw.js/blob/nw12/src/api/v8_internal_helper.cc

@rogerwang
Member

PS: By disabling the recompilation to remove the source code, the result is that the code runs slower with the fullgen compiler. In future we plan to provide some tool so developer could run their code with some data in compile time, so the other crankshaft compiler in v8 would be used to generate faster code. Any thought on this?

@rogerwang
Member

@rajiff the binary code is not readable by end users.
@kevsmt @simonhoss @rotatingJazz

In 0.12.0-rc1 released yesterday the feature is improved as you requested: the size limitation is removed; multiple binaries can be loaded from JS; see the release notes: https://groups.google.com/d/msg/nwjs-general/Sykci3Qhgus/AoF0zT7TEIoJ

@hashseed

@rogerwang we are actually considering caching code after it has executed and including type information into the cache, in order to have the optimizing compiler kick in earlier. But that's not even work in progress yet. But if you want the optimizing compiler to do its job, you will have to include source code.

@ekhaled
ekhaled commented Mar 6, 2015

@rogerwang with the introduction of evalNWBin(), snapshotted code is no longer used by V8 as a template to create JS contexts.
The user has to explicitly call evalNWBin().
In light of that, how do I make snapshotted code available in node-main and / or bg-script scripts?

Thanks for the awesomeness BTW

@rajiff
rajiff commented Mar 7, 2015

@rogerwang do we have a sample package.son or a snippet to check how to use
multiple bin files

On Fri, Mar 6, 2015 at 10:31 PM, Khaled Ahmed notifications@github.com
wrote:

@rogerwang https://github.com/rogerwang with the introduction of
evalNWBin(), snapshotted code is no longer used by V8 as a template to
create JS contexts.
The user has to explicitly call evalNWBin().
In light of that, how do I make snapshotted code available in node-main
and / or bg-script scripts?

Thanks for the awesomeness BTW


Reply to this email directly or view it on GitHub
#269 (comment).

@nicu
nicu commented Mar 7, 2015

@yangguo-chromium-org are you saying that in the future the snapshot might be useless for hiding code? Could we somehow choose the option to hide the code over the earlier optimisation?

Does anyone know of any good alternatives?

I'm about to start work on a project that requires me to obfuscate part of the business logic and I wouldn't want to use a solution that might break in the future.

Thank you.

@hashseed
hashseed commented Mar 7, 2015

@nicu
V8 never supported hiding source code via snapshot in the first place. Consider Function.prototype.toString, which is specified in ECMA262. It won't support hiding source code in the foreseeable future either.

nw.js makes hiding source code possible by sacrificing the ability to run optimized code, since the optimizing compiler compiles from source code. There is no guarantee that the hack that made this possible can be easily implemented for future V8 versions.

@yoyoy
yoyoy commented Apr 23, 2015

hello
is it a way to improve encryption of bin file with nwjc.exe ? an option to enable ?
I can read some datas i the bin file with a text editor :'(
#3399

@darky
darky commented May 12, 2015

Interesting utility
enclose
Maybe it's would be useful

@L3V147H4N

EncloseJS seems really promising for this matter, has anyone tested this with nwjs?

@darkguy2008

EncloseJS does seem good but it does require contacting the author for a payment option in order to be used in a commercial version (contrary to what nw.js offers since it's under the MIT). If he did it, I'm sure the V8 maintainer can do it too, right?

@hashseed
hashseed commented Jul 8, 2015

I'm fairly sure EncloseJS simply uses V8's code serializer to serialize compiled code. Its github repo dates back to roughly the same time when I finished with implementing that feature in V8, except for a few bugfixes. It's described here in the section "Code Cache":
http://www.hashseed.net/2015/03/improving-v8s-performance-using.html

EncloseJS probably patched V8 so that it can deal with missing source code (i.e. no optimizing compile pass) and prevents code flushing (at least it should; not sure if it really does). This is not really supported and may lead to bugs.

Caching code speeds up start up a bit by not having to compile anything, but you would still have to execute that start up code. V8's custom heap snapshot is superior to that: you would simply bootstrap V8 into a state as if the start up code already executed.

@namaljayathunga

How can I hide toolbar programmatically?

@makkesk8

@namaljayathunga check the wiki.

@rohan-deshpande

Chiming in on this topic as it's pretty interesting for me. I'm developing a (hopefully) closed source game engine with JavaScript and NodeWebkit (I'm still on v0.10.5). Is it necessary to do a v8 snapshot of the entire codebase, or can you say, compile your own code this way but load other, open source libraries the regular way so that they get optimisation benefits?

For example, I have all my proprietary code concatenated to game.js, however the libraries that I use are inside of vendor.js. Can the snapshot somehow run the vendor code normally and run the snapshot of the game code or is this an "all or nothing" situation?

@hashseed
hashseed commented Jun 7, 2016

Having a custom snapshot does not affect other parts of V8, including compiling and running scripts. So your game.js can be included in the snapshot, but vendor.js does not need to be.

However, V8 snapshot is not designed to hide source code. Chances are that the source of game.js will be serialized into the snapshot as well. Extracting it from the snapshot would be fairly easy.

@rohan-deshpande

Ah right that's good to know, but as per #269 (comment), doesn't the recompilation avoidance stop the source code from being exposed or am I misunderstanding?

@hashseed
hashseed commented Jun 7, 2016

Well you could definitely hack V8 to drop the source code, and make sure it's not used for display or recompilation, but V8 does not support this out of the box. Unfortunately I don't know whether nw.js has patched V8 to do that.

@rogerwang
Member

@hashseed @rohan-deshpande yeah, NW supports dropping source code for source code protection, check http://docs.nwjs.io/en/latest/For%20Users/Advanced/Protect%20JavaScript%20Source%20Code/

@rohan-deshpande

Thanks @rogerwang, so let's take my example (#269 (comment)), if you used the source code protection for game.js but not for vendor.js would you only see speed reductions in game.js code and not vendor.js code?

@rogerwang
Member

@rohan-deshpande the document said this clearly: "The compiled code runs slower than normal JS: ~30% performance according to v8bench. Other non-compiled JS source code will not be affected."

@rohan-deshpande

Cool! Yes I read that just wondering if I read it correctly or not. Thanks for clearing it up :)

@hashseed
hashseed commented Jun 8, 2016

@rogerwang you could give this a try: run V8 with --ignition --turbo. That forces V8 to use a different compiling pipeline. Ignition is our upcoming interpreter that compiles source to bytecode. We can then optimize from bytecode directly without having to parse from source.

@rogerwang
Member

@hashseed great! will try.

@yanshcherbakovatredspace yanshcherbakovatredspace referenced this issue in SpringRoll/SpringRoll Aug 26, 2016
Closed

offline Game and Security #115

@danschumann

Are there any issues with source code protection mentioned here? http://docs.nwjs.io/en/latest/For%20Users/Advanced/Protect%20JavaScript%20Source%20Code/

I know a previous version had a bug and I'm wondering if my source code would be totally protected.

@rogerwang
Member

@danschumann no there is no issues.

@alphasdev
alphasdev commented Feb 3, 2017 edited

How reliable this way to protect source code now? Is it possible to crack the javascript source code now (last ver nwjs 0.20.1)?

@baconface

@alphasdev How reliable this way to protect source code now? Is it possible to crack the javascript source code now (last ver nwjs & chromium)?

Refer to the two comments above yours.

@darkguy2008

Haha, come on, if he'd release the source code, alphasdev and all of us would be able to know. What is the point of publishing something on GitHub if you are not going to use it for SOURCE CODE ? It's not a file hosting ffs.

@alphasdev

@darkguy2008, off topic.

@darkguy2008

That's not offtopic, we're talking about the code protection which we can't see if the source code is not published. It's pretty on-topic for me.

@baconface

That's not offtopic, we're talking about the code protection which we can't see if the source code is not published. It's pretty on-topic for me.

I cannot see how someone's opinion on GitHub's purpose pertains to or aids this discussion/issue.

@darkguy2008

Ah crap, my bad, I thought this was about that other side-project which uses nw.js and claims to be able to hide the source code but he never releases the source code because he's a jerk. Sorry about all the offtopic xD

@hashseed
hashseed commented Feb 6, 2017

This should become possible soon. V8 is going to switch to a bytecode interpreter and the new optimizing compiler in the next few months. Once that's done, V8 will no longer need the source code, if everything is compiled to bytecode ahead of time.

@danschumann

@hashseed isn't this topic about a similar method of protection? I open up the .bin files with a hex editor and I see a few recognizable names, including strings, but isn't the rest already some sort of byte code which cannot be turned back into readable javascript?

You're just saying that they're adding it to the core V8, including web browsers soon, right?

@jportoles

@danschumann the issue is that currently, in order to compile to a native V8 snapshot, run time V8 optimizations have to be sacrificed, and hence the code ends up being 30-50% slower. A bytecode compiler/interpreter would solve this problem by natively supporting compiled javascript while still being able to do run time optimizations. Thus it would be a win-win for NW.js to adopt this method of compilation vs the existing one, once @hashseed and their team get their implementation ready.

@hashseed
hashseed commented Feb 9, 2017

Currently, V8 needs to include the source string for the functions it includes in the snapshot. Otherwise it cannot recompile these functions to optimized code. Afaik nw.js includes a hack to remove the source string to obscure it, but that prevents optimization.

V8 will soon move to a compiler pipeline that does not need the source string to recompile to optimized code anymore. So for these, we could introduce a new option to eagerly compile functions to include the bytecode in the snapshot, and in return be able to drop the source string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment