Secure Software: How to ensure caller is authentic?

This is one of the largest problems online competitive games have to face. Unfortunately, there's no simple solution. The most effective way of detecting bots or malicious users is via behavioral analysis.


Basically, you can't...

Anything on the client side needs to be considered as public. Sure, you can try to obfuscate the API with various technique but there is always a way to reverse engineer it and build your own botting API. You need to consider that a hacker can control everything on the client side.

What can you protect?

The only thing that you can protect is your server. Hence, if you want to control what your players can or cannot do, you have to validate their every action on the server side. The server must be the source of truth. At this point, if the server can detect any invalid action, an attacker could still build an "invalid" client but the only things this client could do are valid actions. So, it's easy right?

Well, not that much. Trying to validate everything on the server side create many problems. Many related to how smooth the game will run but also, you have to figure out how to include network problems, like a user lagging. For example, if you go to the extreme in terms of protection, it will go like this :

  • The client send action command to the server
  • The server execute the action (if valid) and sends the result to the client
  • The client simply displays the result that the server told them to display.

It's super simple to do and defeat any invalid action, BUT it totally destroys the user experience for anyone with a bad network. When a user press a key to move forward, he expects to move forward right away. Since every action do a round trip to the server side, the users that lag will experience slow action at every turn.

What can you do?

The best idea is to have a mix system. You do the validation on the server side BUT you still "execute" the action on the client side as soon as they happen. That way the user think their action happen at the moment they do them, while in fact they might be done a few milliseconds or seconds later. You are basically doing a simulation on the client side, and if the server confirms to you that everything was ok, that simulation is kept. In the case that the simulation was deemed wrong by the server, these actions are "reversed".

It's kind of a pain to get that sort of system right but it's the only thing that provide good user experience while also completely defeating invalid action.

An easier approach : logging

Since, really controlling everything on the server side can be a pain as it's hard to decide what to do when history needs to be rewritten, an easier approach is to do logging. You let the client do nearly whatever he wants, he is the source of truth, but then, on the server side, you log every action and detect every single invalid action. The invalid actions will still happen but if a client does too many of them, you can safely assume that he is not a valid client and -ultimately- ban him.

About obfuscating : Effort VS Gain

Obfuscating stuff on the client side make it much harder for an attacker to create a botting program so it will discourage many wannabe attackers so you will have to deal with a smaller subset of problematic players.

I'm not an expert in such techniques but it's something similar to:

  • changing all variable/method names
  • inserting useless code to confuse the reverse engineer
  • encrypting the code (but the password is still hidden somewhere in the code...)

It's really just stuff to make it more painful to try to reverse engineer the game client...