javascript-obfuscator / javascript-obfuscator

A powerful obfuscator for JavaScript and Node.js
https://obfuscator.io
BSD 2-Clause "Simplified" License
13.41k stars 1.47k forks source link

Encryption #758

Open anywhichway opened 3 years ago

anywhichway commented 3 years ago

First, I had not looked at your code in over a year. Great progress!!!

Is your feature request related to a problem? Please describe. Not a problem. Just a request for even more obscurity.

Describe the solution you'd like 1) Obfuscator generates a random variable name and places it in a random location in the code 2) Obfuscator generates a random symmetric encryption key and assigns it to the variable 3) Obfuscator re-defiines each function such that:

function(...args) {
    return Function(`return decrypt("${encrypt(f,encryptionKey)}",${keyVarNameHere})`)().call(this,...args);
}

You could obviously encrypt the name of the decrypter.

Want to get even more obscure? You could generate multiple keys and somehow keep track of which key to use to decrypt what.

This could be done after your normal obfuscation run or just standalone.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Well I already did this myself in some code without the rest of your stellar library.

The code I wrote also had the ability to specify an encryption key and then pass it back in at runtime; however, this is actually easier to track down than the random variable approach and actually not as flexible.

I suppose one could also encrypt with a public key and provide a private key at runtime, but I am not sure how much utility that would have.

Additional context Add any other context or screenshots about the feature request here.

BlackYuzia commented 3 years ago

I think this is a good idea.

da411d commented 3 years ago

Great idea, but i think that it has several cons.

First of all, it is bad for environments where eval (and similar) are forbidden.

Second, it is relatively easy to bypass with debugger or even just with spoofing Function constructor:

const originalFunction = window.Function;
window.Function = function(){
  console.log("BOOM!", ...arguments);
  return originalFunction.apply(this, arguments);
};
Function("console.log(123)")();

There exist many "obfuscators", which just encrypt/encode source code and then decrypt/decode and eval it. Maybe the most famous example:

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('2.1(0);',3,3,'123|log|console'.split('|'),0,{}))
anywhichway commented 3 years ago

@da411d I agree on the eval thing; however, if one is domain locking and debug protecting code there is a good chance one is trying to deliver it under license and would simply tell clients that Function eval must be allowed. Regarding the Function constructor spoofing, if debug prevention is on, then using the debugger will be problematic for the interloper. And, there are ways to detect that Function has been spoofed and simply "break" the code as occurs with debug protection. As will any efforts related to the use of JSObfuscator, the point is to make things as hard has possible for the interloper ... making them impossible is not possible.

da411d commented 3 years ago

In #574 is described very interesting idea: to encrypt all code and load the key using ajax

anywhichway commented 3 years ago

@da411d This is actually what I do in my code, see original post "The code I wrote also had the ability to specify an encryption key and then pass it back in at runtime; however, this is actually easier to track down than the random variable approach and actually not as flexible." It is easy to intercept the ajax call and get the key using the browser network panel (which is not blocked by JSObfuscator). This is why I proposed assigning the key to a randomly generated variable name and inserting the variable at the random location. Also, unless I am missing something, #574 will still require an eval type operation on the client.

da411d commented 3 years ago

As addition i can suggest some additional ways to hide the key:

anywhichway commented 3 years ago

@da411d nice!