3

Background: We have the code for a 20 year old MMOG that some people still play, and we have the rights to opensource it. Currently, the server isn't terribly authoritative, i.e. the client is the one that registers hits/kills, etc. The server checks certain things, but if we opensourced it would be easy enough to simply return in the Player::Hit function and then become invincible.

I'm wondering the following: how do I prevent this without rewriting the entire server to be authoritative which would be a huge uplift? That is: I know to an extent it's not entirely preventable, but I'm wondering if we did something like had a private/public key exchange before login to the server, and those keys were gitignored, or something to that effect: could we do it?

More to the point: HOW would one do it? I think the benefits for opensourcing outweigh the risks given that the client has aged poorly and we desperately need help from the public to modernize (if we wish for the game to continue), but before open sourcing I'd rather not rewrite the entire server.

9

NEVER TRUST THE CLIENT!

No seriously NEVER TRUST THE CLIENT!

Third time so you remember NEVER TRUST THE CLIENT! Customer service corollary: The customer is lying!

You need to do all important calculations, dice rolls, etc. on the server side. only input should be taken from the client, and that should be suspect (design your input so that its less abuse-able (your real question?))

IIRC some games will calculate what the screen should look like, including network lag, for your client and do hit detection on that.

You don't really have a choice but to make the client authoritative. This is ever more true if you make the code open source; security through obscurity is no security at all.

  • 1
    Right - I know there's no way to make it impossible without making the server authoritative. However, currently the server isn't authoritative either; the only thing preventing hacking is that it's annoying to hex edit or decompile the client. OpenSourcing makes it really easy to compile your own uber-client. I'd like to make it just as hard as it is today, which is to say: not impossible but annoying enough to prevent casual hacking. Maybe by exchanging some sort of shared secret, using TLS, something like that? – FreeMemory Jul 13 '18 at 18:23
  • 3
    @FreeMemory Secrets and the like from the client can always be spoofed - because it involves the client talking to the server. The only way for a server to check that the client's actions are correct is by validating all the client's actions. If you don't check the client's actions, you're explicitly saying that the client is a valid source of truth. Any communication can be spoofed (i.e. if you try to check the hash of the client binary... the client can always spoof the valid hash for that communication by compiling a normal one and getting the hash from there). – Delioth Jul 13 '18 at 18:38
6

The "NEVER TRUST THE CLIENT!" answer is absolutely right in every technical way, and there really isn't any way to get around that. It is physically impossible to get what you're asking for.

But, rewriting the client & server and make the server authoritative is a lot of work and you may not actually have the time and manpower to be able to do that. Anyway, what's the point of having an open-source client users can't modify it? Maybe take a step back and think about what you are REALLY trying to accomplish for your game & its community.

Looking at this as an X-Y problem, here is an alternate solution that isn't what you asked for but might be a better approach:

  • Stop worrying about cheating as a technical problem and treat it as a social one.

  • Have multiple servers, some that disallow "cheaters" and some that explicitly allow "cheating". (Whatever your definition of cheating is.)

  • If someone hacks the client and is "cheating" on your server that doesn't allow it, that presumably means you caught them because it is having obviously observable effects and making the game less fun for others. Okay, so warn and/or kick offenders (or better, invite them to the right servers to run their "cheat" clients on). Build a culture in your community that people know that some servers are for serious "non-cheaters", and others are for people to "cheat" and try crazy things -- they just need to use the right servers for what they are trying to do.

  • Allow people to connect to servers with modified clients and "cheat" -- that's actually a fun way to play some games, and often doesn't reduce the fun for anyone else. You may be very surprised with your community -- they may come up with cool client mods that although aren't how you thought the game should work, actually are a more fun way to play the game. There is a lot of power in extensibility.

  • Remember, you are talking about a 20-year old game. People are playing it because they like it and are passionate about it. If someone goes to the trouble to modify your client software and recompile it just to cheat, their REAL goal probably usually isn't just to cheat, but to show off their technical skills. Make a welcoming community instead of instantly trying to thwart them, and you'll turn most of these kinds of folks into technical contributers to your game.

  • My reason for wanting to opensource are related to wanting the code in the public domain so we can crowdsource modernizing the client. The graphics are ancient and we don't have enough manpower as-is to modernize, but I know that out there in "the ether" there are people with the know-how, the passion and the desire to help with the uplift. – FreeMemory Jul 13 '18 at 20:58
  • One thing that might be important for cheat servers, make sure that new users can easily see the difference between cheat servers and non-cheat servers (you might want to have that hidden behind an option, default off). Somebody who is very new to the game might not understand what's going on and connect to a cheat server and just get killed instantly, repeatedly until they quit. It would be unfortunate if somebody rage quit the game before even trying it without cheating. – jrh Jul 14 '18 at 19:06
1

Don't bother trying to identify a hacked client

I'm wondering the following: how do I prevent this without rewriting the entire server to be authoritative which would be a huge uplift?

Unfortunately, you can't.

  • Your game state is vulnerable to exploits because the server doesn't protect / manage it.
  • Your server is "vulnerable" because it broadcasts exploited state changes to its clients.

The only way to fix that is to have the server manage the game state.

... That is: I know to an extent it's not entirely preventable, but I'm wondering if we did something like had a private/public key exchange before login to the server, and those keys were gitignored, or something to that effect: could we do it?

That key exchange could probably be easily recovered if somebody wanted to go through the trouble of making a hacked client. The hacked client would just be modified to send data as if it was the real one.

Pitfalls of Kicking / Banning hacked clients

Previous answers have mentioned that you can simply kick/ban hackers, but this is a bit more complex than it might seem at face value.

The success of this depends on:

1. How well the community can identify when somebody is hacking

  • If you see a player teleporting all over the map, sure, it's rather obvious, but can you detect more subtle problems (e.g., Like hacked clients being able to see parts of the map they shouldn't be able to see? Or aimbots?)

  • If your game is competitive, players may argue over who was hacking, or who just had good aim / good reaction time / good luck, etc.

  • If your engine is so vulnerable that clients decide kills / damage, your moderation team will likely have a lot of work cut out for them. Any improvement you make to your game's security will mean less manual work reviewing alleged hackers' gameplay videos, etc.

2. How well the server can identify your players

If you have a large community, attempting to protect all public facing servers where anyone can join will be rather difficult.

Identifying users by IP address

Advantages:

  • Ease of use. No additional signup needed for your game, most users will be able to just download it and play.

Disadvantages

If your servers just accept data from any IP address,

  • Users can easily use proxies to get around IP bans.
  • Legitimate users with consumer internet connections will change IP addresses frequently.
  • From my experience some server admins' attempts to block known hackers with ban ranges inadvertently caused 80% of an ISP's customers to get blocked.
  • New users might try to play for the first time and find out that they are banned for no reason, I'd recommend giving them a way to contact somebody about this.

Other identification methods

  • A game engine I used got around the IP address problem by having users sign up for accounts, and then allowing servers to whitelist only certain players. These accounts were only required for more "serious" servers (for tournaments, etc).

  • On a smaller scale just allowing your servers to be password protected may go a long way towards keeping hackers out of competitive, serious games.

Protecting the game state is the best way to keep hackers away

  • The best way to reduce the risk of a hacked client ruining the game for other clients is to make it so that every change to the game state (that affects other clients) is validated by the server.

  • This way even if a hacked client decides to ignore the server's updates saying that a player took damage, all it does is desync that player's own game.

Design challenges of making a less vulnerable server

There's a lot to cover, but I'll mention the main issues I've faced as somebody who worked on this:

Making a responsive client

  • In order for the game to remain fluid, the client will likely need to run some code on its own and make some guesses on what the next valid frame will be.

  • Some operations that the client does, like mouse movements for example, happen far too fast for the server to validate, though if you don't do this, you may open yourself up to hacked clients that move the mouse impossibly fast or accurately.

  • There may not be an easy answer for all possible exploits, for example aimbots and wall hacks are still being made for even well funded and popular FPS games.

Allowing the client to receive data from the server

  • Knowing what data on the client to throw away when the server sends the client an update is not easy.

  • The client's code may not only have to update the main game's data but also any interpolations that the client was in the middle of, to avoid distracting jittering / rendering glitches.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.