I need to obfuscate my source code as best as possible so I decided to use uglifyjs2.. Now I have the project structure that has nested directories, how can I run it through uglifyjs2 to do the whole project instead of giving it all the input files?
I wouldn't mind if it minified the whole project into a single file or something
UglifyJS is best known as a JavaScript minifier. Minification is a valuable performance enhancing technique as it removes whitespace and unnecessary characters within a file to make it smaller and thus, load faster.
Minification is just removing unnecesary whitespace and redundant / optional tokens like curlys and semicolons, and can be reversed by using a linter. Uglification is the act of transforming the code into an "unreadable" form, that is, renaming variables/functions to hide the original intent...
uglify-es is no longer maintained and uglify-js does not support ES6+.
I've done something very similar to this in a project I worked on. You have two options:
Leave the files in their directory structure.
This is by far the easier option, but provides a much lower level of obfuscation since someone interested enough in your code basically has a copy of the logical organization of files.
An attacker can simply pretty-print all the files and rename the obfuscated variable names in each file until they have an understanding of what is going on.
To do this, use fs.readdir
and fs.stat
to recursively go through folders, read in every .js file and output the mangled code.
Compile everything into a single JS file.
This is much more difficult for you to implement, but does make life harder on an attacker since they no longer have the benefit of your project's organization.
Your main problem is reconciling your require
calls with files that no longer exist (since everything is now in the same file).
I did this by using Uglify to perform static analysis of my source code by analyzing the AST for calls to require
. I then loaded the source code of the required file and repeated.
Once all code was loaded, I replaced the require
calls with calls to a custom function, wrapped each file's source code in a function that emulates how node's module system works, and then mangled everything and compiled it into a single file.
My custom require function does most of what node's require does except that rather than searching the disk for a module, it searches the wrapper functions.
Unfortunately, I can't really share any code for #2 since it was part of a proprietary project, but the gist is:
UglifyJS.parse
.Use the TreeWalker
to visit every node of the AST and check if
node instanceof UglifyJS.AST_Call && node.start.value == 'require'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With