Securing Access To Game Meta DataTo Server (Highest Scores, Total Deaths, etc...)

Started by
2 comments, last by ApochPiQ 12 years, 10 months ago
Something I have been having a hard time thinking about (and not sure if this goes in another forum) is about securing accessing to sending game meta data to a server that will populate leader boards in a number of different stats. The game is going to be sending data directly to a database or a script that will then send the data to the database (probably a NoSQL database like RavenDB). I am just trying to figure out a way that would allow only the game to send data to the database server/script. I am just trying to figure out what kind of methods are available to secure this type of data transfer (sending request over weird ports, create tokens, public/private keys, etc...) or methods for at least detecting when someone is trying to scam the system.
Advertisement
The easiest solution is a simple "shared secret" approach, e.g. using a password that must be included. Then you can ramp up based on how complex you want to get: include a checksum of some kind to ensure the data isn't modified en-route, use public key encryption to prevent anyone but the server from decrypting the submissions so you can avoid people cracking the format, and so on.

Probably the easiest solution that's still secure is to combine the three in a simple way. Structure your message something like this:

{Secret Key, preferably at least 512 bits - 1024 or 2048 is better if you can afford the bandwidth}
{Score data}
{Checksum of the above data, using say MD5 or CRC32 or whatever algorithm suits you; be sure to use some salting}

Then encrypt this using a public key and submit it to the server. The server script should be the only party with the private key, and it decrypts the data, validates the checksum, and processes the request.

This will protect you from pretty much everything but people locally screwing around with the application memory space; it is possible to catch this process in a debugger, for instance, and inject your own data prior to the checksum process so that it appears valid to the server. Or, someone could simply modify their scores in memory prior to the submission entirely, and bypass all of the security you could dream up.

Of course, chances are you don't really need to worry about someone hacking your scores like this; and there are defenses against in-process memory modification (hit up some research on defenses against reverse engineering and copy protection technology, for instance) but they get incredibly complex and are never foolproof.


The common wisdom of any system is never trust anything the user tells you. This is because it is always theoretically possible for the client to screw with your data in some way. No matter how sophisticated you get, it's usually fairly trivial to bypass if you know what you're doing.

That's not meant to be discouraging; just keep it in mind when designing anything that involves user-submitted data. Obviously at some point we have to quit being paranoid and just deal with what we're given, because otherwise we'd never get anything done. It's up to you to decide how much effort you want to expend in defending your system; just remember two things: (A) someone will always be able to break it, and (B) the more complex it is, the more interesting a challenge it is perceived to be by the kind of people who screw with this stuff, and therefore the more attention you will probably garner from the very people you're trying to thwart.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


This will protect you from pretty much everything but people locally screwing around with the application memory space...
[/quote]
Well you're including the secret in the application, so I can copy the secret and build whatever I want. But leaving that aside your basic idea is still probably enough to deter most cheaters, while being quite reasonable to implement.

There are some other approaches you might like to think about. One idea is to place a high computational "barrier to entry" to submit a score. To submit a high score, you must submit the game data which generated the score, the server must then verify to ensure that no cheating took place. This means that a would-be cheater must either play or simulate an entire, valid game session to submit a score. This isn't foolproof, it only detects "out of range" cheating, it cannot detect aimbots or wallhacks. It could also be too expensive to validate on the server (depending on the nature of the game and the number of players).

Another option, assuming multiplayer, would be to require that all participants in a game upload the results at the end. You can then discard results that do not match between players. You would need some authentication mechanism (such as a shared secret like a password, or a per-client public/private keypair) to ensure that players do not spoof one another.

This also isn't foolproof, a group of cheaters could gang up to inflate their scores, or a lone cheater could create "dumb" player-bots to do the same. A client could be modified to only submit "good" scores, by not sending any ones the cheater deems poor. If the games are between more than two players you could relax the rules and create a hueristic of what you will accept (e.g. 75% of players agree on the outcome).
Good point on the shared secret; you could add some layers of security (more public/private key stuff) to ensure that the secret isn't easily detectable by memory scans etc., but it's still vulnerable to modifications to the game binary at the end of the day. Again, depends entirely on how much effort is justified in securing the thing.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement