1

I have express application in nodejs:

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

My js files which go the browser are in /public folder. I want to obfuscate them automatically in runtime, so it'd be hard to read them in the browser. Is it possible to tune this app setup somehow?

2
  • 5
    Why are you trying to obfuscate the code in the first place? If you're that worried about someone reading it (which they will find out what it does anyway) then you probably shouldn't be sending it to the browser. Commented Nov 28, 2014 at 20:02
  • It should execute in the browser, but should not be user-readable. This is what is obfuscation. Commented Nov 28, 2014 at 22:03

6 Answers 6

7
+50

Don't obfuscate at runtime. Create a build step which obfuscates your code and serve the obfuscated code in production.

Install UglifyJS:

npm install -g uglify-js

Then you can run the following command to obfuscate your code:

uglifyjs < src/script.js > dist/script.js

Alternatively, install grunt and the uglify plugin:

npm install -g grunt-cli

npm install --save-dev grunt grunt-contrib-uglify

Create a file called "Gruntfile" in the root of your project with the following contents:

'use strict';
module.exports = function (grunt) {
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.initConfig({
        uglify: {
            all: {
                files: {
                    'public/scripts.js': 'src/**/*.js'
                }
            }
        }
    });
    grunt.registerTask('default', ['uglify']);
};

Run grunt from anywhere in your project to obfuscate your code. Update the index.html file in public/ with a <script src="scripts.js"></script> to load the obfuscated, concatenated scripts.

If order matters, list your scripts in order:

files: {
    'public/scripts.js': [
        'src/1.js',
        'src/3.js',
        'src/2.js'
    ]
}
Sign up to request clarification or add additional context in comments.

8 Comments

i need runtime obfuscation
That's stupid. Most obfuscators are really slow, and your visitors aren't going to wait for your code to be minified server-side or client-side on every GET. And if you do it client-side, it's pointless, because anyone can pull up the network tab and examine the body of the HTTP request that delivered the script before it was obfuscated.
Is caching forbidden?
You could cache runtime-obfuscated scripts, but at least one of your users is still going to wait for it. No one ever has to wait if you obfuscate the script pre-deployment.
I refuse to help you do something so stupid. Find someone else who doesn't care about your users.
|
5

So, you can't actually keep a user from reading your javascript when it's sent to the browser. You can make it very hard, but a determined user will always be able to transform it to something readable through a combination of automated tools and manual labor.

In short, there's no DRM for JavaScript (or any code, for that matter). If you want to protect the intellectual property in your scripts, put a copyright notice on them. If you think someone stole them, talk to a lawyer.

It's certainly worthwhile to minify your JavaScripts, but the only reason, in my opinion, to obfuscate them is because your stupid boss told you to.

If you want to obfuscate it, check out the answer to this question: How can I obfuscate (protect) JavaScript?

Note that obfuscation is rather expensive, so you really don't want to do it at runtime. You should simply apply it to your javascripts when they change using a build tool like grunt or bower (personally I prefer grunt). These systems have plugins like this to perform the obfuscation.

2 Comments

How are you going to deobfuscate this: discogscounter.getfreehosting.co.uk/js-noalnum_com.php ???
@stiv: that code doesn't even run, but older copies of firefox will turn a function's toString() code into a parsed representation (without comments), so it might very well reduce that down to more basic terms...
2

You can use UglifyJs in your node application and do what you need using its API. Check out their documentation for further details.

Example from Unglify docs

var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;

var orig_code = "... JS code here";
var ast = jsp.parse(orig_code); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var final_code = pro.gen_code(ast); // compressed code here

P.S. People noting that it is slow and blah blah are of course all correct, but hey, if you need it here it is, I just don't understand why judge and post opinions in response to a clear question.

Comments

1

You can obfuscate the code using command line utility, such as this:

app.use('/javascripts',function(req,res,next){
    if (process.env.OBFUSCATE != 1){
        next();
    }
    var cmd = "java -jar ./gcc/compiler.jar ./public/javascripts" + req.url;// + "> ./tmp" + req.url + ".tmp";
    exec(cmd,function (error, stdout, stderr){
        res.write(stdout);
        res.end();
        if(error !== null){
            console.log('exec error: ' + error);
        }
    });
});

Comments

1

My tips are easily bypassed, but without be careful, we can be trapped. And it is only client part, not nodejs part.

Only live view of the page

You can replace or remove script tag with javascript for hide this in live view of the page. But if you watch directly the network, you can see easily the javascript file/code.

<div id="RemoveMe0">
    <script type="text/javascript">
        //This code it is hidden to live view.
        var my_var = 5 + 5;

        $('#RemoveMe0').remove();
        //or document.getElementById("RemoveMe0").innerHTML = "";
    </script>
</div>

For include javascript :

<div id="RemoveMe1">
    <script type="text/javascript" src="Javascript/MyJS.js"></script>
    <script>
        //Your include it is hidden to live view.
        $('#RemoveMe1').remove();
    </script>
</div>

Only direct view

Put your files in an HTML file (myfile.js to myfile.html), like this on a direct view you can execute a javascript function.

function Hello() {
    alert("Hello");
}
Hello();
//<script>document.body.innerHTML = "";</script>

Conclusion :

For this tip, rename file or use .htaccess. And like first tip, if you watching the network you see full file.


Or minize/parse your JS

You can use tool like this :

Comments

0

I see you are using express and EJS. What I do is create another folder called jsobf that holds the obfucated files. Basically duplicate all your js files with the same name if you want.

In EJS you can do if else check in your ejs files like this :

<% if (process.env.NODE_ENV === "production") { %>
    <script src="/jsobf/myjavascriptfile-prod.js"></script>
<% } else { %>
    <script src="/js/myjavascriptfile-dev.js"></script>
<% } %>

At the top of the file where you do app.listen.. declare you a global variable:

const isProduction = true;

app.listen(PORT, function () {

    if(isProduction){
        process.env.NODE_ENV = 'production';
    }

});

Then all you need to do before you deploy your code is manually obfuscate your code at a site like obfuscator.io

In your dev branch set the isProduction to false and in production branch to true. This way when you are developing everything is taken care of for you.

This may not be the cleanest solution but it works perfectly fine for me if you dont care to obfuscate manually before production deploys.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.