javascript-obfuscator / webpack-obfuscator

javascript-obfuscator plugin for Webpack
https://github.com/javascript-obfuscator/javascript-obfuscator
BSD 2-Clause "Simplified" License
853 stars 84 forks source link

process variable is undefined when use DefinePlugin #123

Open Katarn opened 2 years ago

Katarn commented 2 years ago

I wrote about this bug in another issue, but it is already closed, it would probably be more correct to make a separate issue in a more suitable repository for this.

I made a minimal example.

Just run npm ci && npm run build. After that, in the dist directory, you will see the main.js file. Open it in a code editor and you will see something like:

....shift())}}(n),process[r(309)][r(311)]&&console[r(302)](r(311))})();...

Of course, the process variable is undefined. Moreover, it should not be in the code, it should either be replaced with true (according to this line), or, with "smart optimization", the if (...) check block should not exist at all, since it will always be executed.

Then you can uncomment these two lines (not necessarily at the same time, you can uncomment them separately) and see how the code is generated in the main.js file.

thierrymichel commented 2 years ago

This is how I fixed it:


/* javascript-obfuscator:disable */
const endpoint = `${process.env.VUE_APP_API_DOMAIN}/api/v1`
/* javascript-obfuscator:enable */
rinogo commented 2 years ago

This problem still exists. The problem is that javascript-obfuscator's stringArray option/mode replaces env and VUE_APP_API_DOMAIN (or some other env variable) with string array lookups for the property names.

Once those replacements are made, the substitution logic performed by DefinePlugin and dotenv-webpack won't work.

One way to fix this is with stringArray: false. However, that effectively disables much of the obfuscation.

Another solution is to use the webpack-obfuscator Webpack plugin instead of the loader. The webpack-obfuscator plugin can run after the Dotenv (or similar) plugin which will enable that plugin to make the substitution first.

Yet another solution is effectively the same as proposed by @thierrymichel. I didn't want to use a template literal since I'm using the value in an expression, so I ended up using something like this:

if(/* javascript-obfuscator:disable */process.env.NODE_ENV/* javascript-obfuscator:enable */ === 'development') {
    ...
}

//or

/* javascript-obfuscator:disable */
if(process.env.NODE_ENV === 'development') {
/* javascript-obfuscator:enable */
    ...
}

Although the first solution in the code excerpt above is messy, it isolates the identifier better and will likely lead to fewer obfuscation errors.