1

I'm currently developing a fully-browser-based game (a la Cookie Clicker) and I'm trying to minimize the possibility of users exploiting the visible JavaScript to cheat their game saves. For the sake of explanation, let's look at a hypothetical function;

let user = {
    money: 0
};

function addMoney(amount) {
    user.money += amount;
}

If this were a real function in my game, any user could simply pop open the developer console, type addMoney(1e100), and instantly ruin any possibility of competitiveness among my potential player-base.

I'd like to know if there's any way to disable external JavaScript input (be it through the developer console or through the use of javascript:() injections within the address bar) and if such a thing doesn't exist, is it at least possible to detect external JavaScript as opposed to JavaScript that was executed internally by the site itself?

UnicornSnuggler
  • 107
  • 1
  • 9
  • always expect the user to change your js, and code the server to protect from this. – Steven Stark Mar 29 '19 at 19:11
  • I don’t think it’s possible to do exactly what you’re asking, but if you base your logic on user input (like ’click’ events) you could write anonymous functions in the event handlers and check the `isTrusted` value of the event. – Nils Lockean Mar 29 '19 at 19:14
  • If the game is entirely browser-based the best bet you probably have is obfuscation, screwing with `window`, and making sure your code is in a module so nothing is global. If you have a server, handle all important game logic there so they can't cheat at all – Andria Mar 29 '19 at 19:15
  • let me see if I understand. Your game doesn't interact with a server? How are you going to save your players improvements? You are going to trust what the front-end says? If that's the case, what does prevent a user from using postman or a curl request to save any data in your server. If you are not saving your user's data in the server how do you get their highscores to compare? the user would be cheating just for themselves? – Gabo Mar 29 '19 at 19:15
  • wrap it all in a closure, subscribe dom methods from within to reach from the outside. that way, the user cannot directly call your methods. However, there is still the possiblity to set breakpoints and drill into scope that way, but i suspect hiding global refs will cut down on cheating quite a bit. You can also use WebWorkers to "hide" globals, with some sort of checksum/auth/sanity check on the incoming messages. Basically, JS's security model is reference base, so you have to remove the refs. you cannot stop user JS, don't even bother trying. The other options is to do it all server-side. – dandavis Mar 29 '19 at 19:18
  • @NilsLockean, can you link to an example of what you're suggesting? – UnicornSnuggler Mar 29 '19 at 19:42
  • @Gabo the game saves will be reporting back to a server, but the game logic is all in the front-end because I don't want to have to make perpetual AJAX calls every time the user wants to do something. – UnicornSnuggler Mar 29 '19 at 19:43
  • Even though you prevent user from editing your javascript or running its own in the browser. Users will be able to intercept or create their own requests to your server to save a "corrupt" state. Maybe your solution could be to validate states, for example, if you create a level where your user can only earn 5 points tops, the save status should check that. Even if you ofuscate and minify your js code, they can always watch the variables and edit them. – Gabo Mar 29 '19 at 20:17
  • Maybe you can somehow log or create a validation variable with some logic hidden in your obfuscated code so editing just the values that indicate something useful makes the saves corrupt – Gabo Mar 29 '19 at 20:19
  • "Even if you ofuscate and minify your js code, they can always watch the variables and edit them. – Gabo "(previous comment) - If a 'cheater' is sufficiently determined (and skilled), you won't stop them, but obfuscating/minfying the code will make it much more difficult and deter the vast majority of them - certainly the casual ones. There are many available tools for doing that, and it is very easy to do.. – T G Mar 29 '19 at 23:14
  • Honestly, I feel kind of dumb for not considering minification and obfuscation. I just found an obfuscation tool that makes it _nearly_ impossible to unravel the original code and apparently it also weakens the user's ability to use the console and dev tools in general by inserting empty functions and whatnot. @TG If you make an actual answer with the obfuscation / minification suggestion, you'll get the solution credit here – UnicornSnuggler Mar 30 '19 at 07:15

1 Answers1

1

Say no more:

If a 'cheater' is sufficiently determined (and skilled), you won't stop them, but obfuscating/minfying the code will make it much more difficult and deter the vast majority of them - certainly the casual ones. There are many available tools for doing that, and it is very easy to do..

This is a very good one to use:
https://developers.google.com/closure/compiler/

T G
  • 445
  • 3
  • 7