views:

897

answers:

12

Suppose you created an online game in HTML5/Javascript. All the code would be downloaded into the users browser, and they would run the game.

What is stopping someone from copying the game onto their computer, and injecting functions and modules to cheat? IE, they could write a function that autoaims at the nearest enemy sprite for example.

Is there any fundamental way to protect people from doing this sort of thing by designing your game code in a certain way?

alt text

+33  A: 

What is stopping someone from copying the game onto their computer, and injecting functions and modules to cheat?

Nothing.

Is there any fundamental way to protect people from doing this sort of thing by designing your game code in a certain way?

Nope.

JSBangs
Google had some interesting work being done to protect their Pacman game from a few weeks ago.
Chris Stewart
You can put a whole bunch of effort in to obfuscating your code to make it harder, but as @js-bangs indicates, there is functionally no way to prevent it entirely. If it operates client side, the client has it and can modify it.
g.d.d.c
@Chris Steward: But at the same time, Google's PacMan is a good example that even the hardest obfuscation won't be able to ultimately stop people from copying it.. After all, people were able to save it..
poke
@JS Bangs: your answer is just so wrong and uneducated it hurts reading. Contrarily to you I **did** work in the (commercial) computer gaming industry. Games like Blizzard's blockbuster Warcraft III are replicating the entire game state on the server side and only ever transmitting the inputs the player made. It is impossible to play on Battle.net by sending invalid game state. In addition to that, should a "bot" be faking inputs, there are a *lot* of heuristics allowing to catch bots and there are regularly licence keys voided for **busted** "botting" purpose. You are just **SO** wrong.
Webinator
@Webinator - You imply yourself that people figure out how to make bots, which, to me, only reinforces the first part of JS Bang's answer. You go on to say that there are "a lot of heuristics" used to catch bots, which strikes me as incredibly domain specific and not fundamental to the design of the game itself. All you prove is that it is possible to *deter* cheating, and that with a lot of development investment, cheating can be minimized.
Daniel Schaffer
@Webinator: I'm assuming we're talking of "pure" JS games (ie on the client). No server-side controls involved.
nico
@Webinator, I was also assuming that we were talking about a mostly or entirely client-side javascript game. Obviously, if you put the entire game state on the server and post back every user action, you can minimize cheating, but that's not the situation that I believed the OP to be describing.
JSBangs
Could you be able to pass a javascript object containing functions to the client from the server in an encrypted manner. The client shouldnt be able to get to inner functions of a closure. Only the accesable functions can be accessed. Like for example a single startMainLoop() function. Basically try to pass an encrypted closed source closure object from the server
Raynos
+8  A: 

In short, no. However, you can obfuscate Javascript to make it much more difficult.

For things like scores, a user could in theory POST any score to your handler script. In this case you could use a session and regularly post back to the server through AJAX.

DisgruntledGoat
even with the worst obfustication they can just interpret it on the fly using Firebug and figure out which does what.
Kim Jong Woo
@Kim Jong Woo: Yes but it's still not straightforward.
DisgruntledGoat
straightforward enough for someone who has the intention of hacking or cheating browser multiplayer games, which I think is what OP is concerned about.
Kim Jong Woo
+25  A: 

This is why most JavaScript games rely heavily on a server state, to prevent cheats.

Luca Matteis
Out of interest, did you **mean** 'relay,' or 'rely'? They both make sense, but each seems to imply something slightly different. =)
David Thomas
Every other answer has said *it can't be done,* which is of course wrong. It can be done - just do all computations on the server. This introduces lag, which makes a real-time game difficult. The more real-time you want it, the more security you must sacrifice (this is true of all games, not just javascript ones)
BlueRaja - Danny Pflughoeft
BlueRaja: and how would that prohibit one from writing a function that autoaims at the nearest sprite? Ok, it makes things like wallhacks harder, but user input can still be faked, and output can still be parsed and shown differently.
Konerak
+5  A: 

You're attempting to do the impossible. The best advice I can give you is that if you are plan on persisting any data like coins/money/gold, levels, whatnot you make sure you never trust the client and make as much logic server sided as a possible.

Chris T
+5  A: 

I like the question, and while there are probably better answers, here are a few off the top of my head that may (or may not) work:

  • Obfuscation. Yea, it's not guaranteed and someone can eventually get to it, but it's a pain in the butt to deal with sometimes.
  • Generate the JS with a new temporary token each time. You may be able to templatize the .js running the code and insert a server generated token that differs per each instance. The token could be temporary and it could be one way to validate the authenticity of the code
  • There's probably some way to determine the proper location of the script being run - but this could probably be faked

In general, its hard, and all of the suggestions above can be worked around. I guess the key is to make it hard for them to cheat, but given that there are cheaters for even secure online mode games, it's going to be hard to prevent JS games from being susceptible to that as well.

SB
+7  A: 

Is there any fundamental way to protect people from doing this sort of thing by designing your game code in a certain way?

The only sane method is to keep critical pieces of the code on servers you control and never give it to the users' computers at all. The hard part is making this square with keeping the game fast enough to be playable.

Donal Fellows
A: 

Disclaimer: This is a terrible method and probably too much effort than it is worth.

Suppose that you had a method of processing the javascript code before you sent it.

First of all, every method has a ident variable which is attached to the result of every function (i.e. every function would return {ident:"special code",result:"actual useful function result"}). You also have a testIdent() function which would accept the function name to call as well as "test data" to give it (if any is needed). The purpose of testIdent() would be to send the ident returned from said function to the server for verification (the idea being that the server can request a test whenever you deem it appropriate). The ident for every function should be randomized and recorded specially for the specified user before sent.

Second, before the code is sent to the client, the function order is randomized and function names are obfuscated in some random fassion. This way there is no way for a hacker to look for some variable ident in function x() as it will be named randomly. Also, it would be another plus if every variable name is obfuscated randomly as well, just to add yet another step to the complication and headaches of... well... everyone (I told you this is a terrible method).

Now, assuming proper steps are taken to make sure the code will always function correctly, hackers are very cleaver people, and there are still ways for hackers to track this code if they are determined enough. At least one way will be to search for key code structures, such as a switch statement with a certain number of elements, or a for loop with x number of statements, etc. While each of these can be countered, say by adding dummy case statements in the switches or a couple of if(true) bits randomly throughout the code, countering hackers will always be a constant (and possibly a loosing) battle.

Hopefully this can give you some ideas. I don't know how someone would implement this exactly, but it is at least an idea.

Good luck!

Mike
+1  A: 

You can put everything the code ever calls inside of a closure:

(function() {
  var cantSeeMe = function() {
    // do some game stuff!
  };

})();

Outside of the closure, it will be very difficult to get at the code for "injection hacks" (overriding a function on the console for instance). This wont stop someone from rewriting your code, but passing things through a packer, or even closure compiler can make your code pretty hard to read/modify... (take a look at jQuery min

All in all, ANY game running client side is hackable.

gnarf
A: 

travian(http://www.travian.us/) is a good example of a larger scale game that runs in DHTML and it has a ton of issues with client side abuse. Just installing grease monkey in firefox opens a rather large door to all kinds of exploitative behavior. That said, they seem to keep the game somewhat functional since most of the exploits seem to revolve around automation of common in-game tasks and not direct violations of the internal domain logic of the game. Keep in mind that this example is far from being run with only JS and relies largely on server side controls.

tsgrasser
+5  A: 

Some thoughts

Server side:

  • Store the games internal state sever side and check the input send by clients on the server.

  • Autoaim: Create fake sprites which are invisible to normal players, if they get hit too often you have a bot. (will not always work as the bots may be updated to check for invisibility)

  • check client reaction time to changes on the server, check for too many too fast reactions. (has to accept a large number of fast responses before reacting as a human could react fast and the time has to account for the network delay to catch anything). Give the player some sort of captcha, a regular player would never see it.

Client side:

  • use obfuscation to make it harder to interface with your code

  • check for functions defined in the hacks you know about. Has to be modified/updated often as the creators of such hacks can work around those.

  • Game design: making your game less repetitive this makes it harder to write tools/bots for it.

  • update the client to change parts of its structure from time to time. While this will not stop bots it will take work to keep them running. Either make it transparent to the user or disguise it with a new feature.

Important: make sure your server interface checks the user input, obfuscation and client side checks wont help against someone writing their own client.

josefx
+2  A: 

I think the way to go would be to write the client in a way such that you dynamically alter the client code and verify the use of thusly created code on the server.

E.g. have a namespace like this

window.mynamespace = {

    foo : function(){
        // some stuff here
    },

    bar : function(){
        // some more stuff here
    } 
}

which contains all your client code and make all your server methods require a token that is the result of a previous dynamic evaluation of the code base. make this harder by redefining methods and changing method names. Here are a few sample challenges (this only makes sense if challenges are created dynamically and not predictable). All contain a task first and then a challenge that will be used to create the authorization token for the next request. (These are response objects from the ajax calls). Basically the task will be eval'd and the result of the eval'd challenge will be the next token.

{
    task: "mynamespace.baz=mynamespace.foo;mynamespace.foo=undefined;",
    challenge: "mynamespace[11].toString().substr(10,22)"
            // get part of a well-known functions source code
}

{
    task: "mynamespace.bar=function(){ /* new code here */ }",
    challenge: "var xy=0;mynamespace.each(function(item){xy+=item.toString().lastIndexOf(';')}); xy"
            // accumulate the last index of a semicolon in all elements
            // of the namespace
}

To beat that and still get valid authorization tokens, the client would have to write an entire javascript emulation layer. Although that can be done, I would try to make the server code change in fundamental ways very often to make this technique almost impossible (so the emulation layer won't know what to emulate).

seanizer
would the downvoter care to elaborate?
seanizer
+1  A: 

they could write a function that autoaims at the nearest enemy sprite for example.

You can do this even for games were most processing happens server-side! You just need to analyse the display quickly enough.

You can even re-implement parts of the game AI to try to predict how bots will move. Not an easy task if you don't have access to the game's source code but if you log lots of gameplay time, you could apply machine learning techniques.

Is there any fundamental way to protect people from doing this sort of thing by designing your game code in a certain way?

Don't forget that you can change the game itself, not just how it is implemented. For instance, use randomly-generated levels rather than static ones, use human players rather than bots, make your art/sprites more complex, make more use of audio, put a limit on how fast the cursor can be moved, add cooldown times to weapons, add hidden hazards, and so on.

Artelius