17

I'm working on a web application in HTML/JavaScript, and I want to prevent users from calling functions in their browser console in order to avoid cheating. All these functions are contained in a unique file called functions.js which is loaded in the head of the index.html file.

After a search on the web I found this solution, which works fine in Google Chrome, but it is inefficient in other browsers such as Firefox:

var _z = console;
Object.defineProperty( window, "console", {
    get : function(){if( _z._commandLineAPI ){ throw "Script execution not permitted" } return _z; },
    set : function(val){ _z = val }
});

Is there a general way to disable functions call from console? Does it depend on the browser or is it just a problem of scoping or maybe something else that I have ignored?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    Even if you did, you could still execute functions from the browser bar – Mike Robinson Oct 07 '13 at 22:31
  • What you found does disable the `console` object for your script, but does not hinder users to use the browser console. – Bergi Oct 07 '13 at 22:32
  • 1
    Whatever you do in a browser the user can undo. You can't hide anything, and whatever you disable the user can enable again. I'm not sure what 'cheating' you're trying to prevent, but doing it client side won't be reliable. –  Oct 07 '13 at 22:33
  • Javascript is a client side technology. They will *always* be able to manipulate the client side of it. That is why no authentication is ever done purely client side. – Travis J Oct 07 '13 at 22:34
  • possible duplicate of [javascript security concern](http://stackoverflow.com/questions/12864537/javascript-security-concern) – Bergi Oct 07 '13 at 22:34
  • 2
    just make sure that there is no weak point in your js. to be precise, don't use global variables, encapsulate the whole thing in a closure, minify your js file to make it harder to back-engineer. if you are concerned that users might use js to talk to your server and cheat, you should read about permissions. – lordvlad Oct 07 '13 at 22:36

6 Answers6

16

Is there a general way to disable functions call from console?

No. there isn't: Never. Well, apparently, Facebook found a way in Google Chrome to do so: How does Facebook disable the browser's integrated Developer Tools? - though, I would consider it a bug :-)

Is it maybe something else that I have ignored?

Yes. JavaScript is executed client-side, and the client has the full power over it. He can choose whether or not to execute it, how to execute it and modify it as he wants before executing it. Modern developer tools allow the user to execute arbitrary functions in arbitrary scopes when debugging a script.

You can make it harder to introspect and use (call) your code by avoiding to expose your methods in the global scope, and by obfuscating (minifying) the source. However, never trust the client. To avoid cheating, you will have to perform all crucial task on the server. And don't expect all requests to come from your JavaScript code or from a browser at all; you will need to handle arbitrary requests which might be issued by some kind of bot as well.

wp78de
  • 18,207
  • 7
  • 43
  • 71
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 2
    @KeoStrife: What exactly do you mean by "facebook console", opening your browser's devtools console on https://www.facebook.com/? What would not work there? What browser do you use, what did you type in? – Bergi Feb 11 '14 at 21:07
  • @KeoStrife: I see what you mean now. [How does Facebook disable Developer Tools?](http://stackoverflow.com/q/21692646/1048572) – Bergi Feb 12 '14 at 15:15
2

Rather than eliminating access to the console, just code your javascript so it doesn't pollute the global namespace. It will make it much harder (or in simple cases virtually impossible) for code executed from the console or address bar to execute your code: https://stackoverflow.com/a/1841941/1358220

It's also worth noting, if you have some code you want the user not to be able to edit or execute, move it to the serverside and only expose the result to the client. You're currently trying to fix a bad design design with a bad coding decision. Improve your design and the implementation will take care of itself.

Community
  • 1
  • 1
Bob Davies
  • 2,229
  • 1
  • 19
  • 28
  • 4
    Wrapping code in a closure isn't a bad idea, until the user steps through it. – Travis J Oct 07 '13 at 22:35
  • Aye it's not perfect, but since he's not quoting the code he's trying to 'protect', a closure is potentially a less offensive solution than crippling the console. – Bob Davies Oct 07 '13 at 22:36
  • By that reckoning editing the code to reinstate the console would have the same issue. Like @Bergi said, there is NO way to do what he's asking, so my suggestion is just a slightly more appealing technique to achieve the closest he could get :) – Bob Davies Oct 07 '13 at 22:44
0

Minify your JavaScript source to obfuscate any meaning. It won't make it impossible to cheat, but really hard to figure out ways to cheat.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
lordvlad
  • 5,200
  • 1
  • 24
  • 44
0
if (window.webkitURL) {
    var ish, _call = Function.prototype.call;
    Function.prototype.call = function () { //Could be wrapped in a setter for _commandLineAPI, to redefine only when the user started typing.
        if (arguments.length > 0 && this.name === "evaluate" && arguments [0].constructor.name === "InjectedScriptHost") { //If thisArg is the evaluate function and the arg0 is the ISH
            ish = arguments[0];
            ish.evaluate = function (e) { //Redefine the evaluation behaviour
                throw new Error ('Rejected evaluation of: \n\'' + e.split ('\n').slice(1,-1).join ("\n") + '\'');
            };
            Function.prototype.call = _call; //Reset the Function.prototype.call
            return _call.apply(this, arguments);  
        }
    };
}
Pranay Soni
  • 1,056
  • 10
  • 18
0

If you want to avoid "cheating", you will need server-side verification of user input. The client can only send the server information according to a server-side defined protocol, and thus cheating is impossible, unless your protocol has security leaks (and most protocols do, especially new protocols).

Sandboxes such as the Facebook API, Google Caja and more allow you to arbitrarily enforce any constraints by "re-writing" the language (they run a parser on and basically re-compile user-given code and make everything that is unsafe safe). This works as long as you can make sure that user code can only run inside these environments. This way code from other users cannot mess with your client, but you can of course still mess with your own client.

Domi
  • 22,151
  • 15
  • 92
  • 122
0

For those looking for it today:

This obfuscator tool: https://obfuscator.io has the feature "Debug Protection" this blocks the console and even the inspection mode of your browser. It also stops any javascript when the inspector was opened.

Works like a charm.