1
\$\begingroup\$

I'm currently working on the backend to my game, which is an MMO RPG-style game. I have my game client build, game server build, authentication server and player data server set up (albeit, locally currently - servers are expensive O.O) and I'm mostly happy with the current implementation, but I can't figure out a way to exclusively allow my game server write access to the player data server.

Currently, the player data server (API) once authenticated via the auth server will serve (read-access) a players current data, such as; level, gold, inventory content etc. basically game-state for that player character. That's all good and working.

During a game session, the players state is going to change, and I'm going to need to update the player data server at the end of a game session, to persist the data for next time they log on. I'm just having a total mental block on how to securely implement this... Currently, I have a 'Game Server' authorisation level to my API which gives write access to a specific player on the player data server in conjunction with a session token for a specific player - but this method involves me having the email + password for this 'Game Server' level access account hard coded on my game server so that it can connect with this level, which (and I'm not a security expert by any means...) seems like a really bad idea!

Any and all advise appreciated! If I missed anything pertinent / you need more info, just ask :)

New contributor
AndyPick is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
2
  • \$\begingroup\$ I'm a little confused here. If I understand correctly there is an application server (the game server) and a storage server (the data server). Are you running both? Is the data server third party? Will the players run the game server? Do you plan to open source it (and thus reveal the credentials)? You don't have to hard code the credentials, you can have the game server read them from a file, which can be perfectly fine, or the worst, depending on the situation. Also, given that this is multiplayer, I hope you are not giving access to the data server from the client. \$\endgroup\$
    – Theraot
    Jan 11 at 20:55
  • \$\begingroup\$ @Theraot Yes, these are separate servers, and no, nothing is third-party. Currently, the game server is (I'm using Unity game engine) just a server build with a bunch of server specific logic etc. and it's hosted on a scalable VM depending on hardware requirements for number of concurrent users. The data server is just a database hosted on a separate server (just my local host currently in testing) as it doesn't need the same level of hardware as running the game server. No, it's not going to be open sourced, only my dedicated server. Client only has read access to the player logged in. \$\endgroup\$
    – AndyPick
    Jan 11 at 21:28
1
\$\begingroup\$

First of all, most hard-coded credentials vulnerabilities are about a "master password" or similar, that anybody could use to log-in. In other words: a backdoor. I don't think that is not what we are talking about here.

And about the issue of third parties that may attempt a connection, you want a firewall solution. For example, have a firewall configured to only let through connection to the relevant network port from the MAC/domain/IP range of the game servers.

If the above answer is not satisfactory, keep reading.


Storing server credentials on the server is the way it is often done. It is common practice. It makes sense.

Before we go on, I want to point out that if the credentials are hard-coded, it also means you would need to build the game server software again if you need to change the credentials, which is an issue by itself.

Why is this considered OK to store credentials on the server? After all, if the hosting of the game server is compromised, the attackers could get the stored credentials (hard-coded or not). It is considered OK because if the server is compromised, then it is compromised. The attackers are already on the other side of security. We don't want the situation to get to that.

Instead of trying to figure out how to have the server run in a hostile environment, we should be trying to figure out how to prevent it.


However, if the concern is a data breach. Can we take further measures? Yes. The way to not have credentials for the data server on the game server at all, is to derive them for each player. That is, you will be creating accounts for each player on the data server. No, no, pay attention.

When the player logs into the game server, it will attempt to log-in to the data server with that password (or a key derived from it). The game server should not store the password nor the derived key, and also should not do any verification on the password. Then the data server can do authentication and return a session ID to the game server.

In other words, the data server will be both an storage server and an authentication server (or it will further delegate to the authentication server). From here on, I'll talk about the authentication server.

Done this way, if there is a data breach, malicious users won't find there any player passwords there, nor credentials for the data server or authentication server (except - perhaps - credential for minimal read only access, if that is something you need).

On top of that, you can have a password for the game server, stored on it. Then code authentication to require both the game server password and a player password. Which sounds like what you are doing. If the game server password is stolen, it will be useless without the player passwords.


However, one thing is a data breach, and another thing is a hosting under the control of attackers. For example, if the server is compromised, the attackers could add code to the hosting to intercept attempts to log-in from the players, and store the passwords.

So, can we take further measures? Yes, with the goal to protect passwords even in this situation, yes. This is my proposal: Implement PGP on the client. You are going to generate a public-private key pair for your authentication server. The public key - as the name suggest - will be public, and deployed with the client.

Then the client can generate a random symmetric key, use it to cipher the password, and also cipher the symmetric key with the public key. That way, to get the password we need the private key, which - as the name suggest - should remain private, to get the symmetric key to get the password.

And only the authentication server will be able to do that. If the game server is compromised and the attacker intercepts the communication on it, they will not be able to open them. However, we need to invalidate them, so the attackers cannot reuse them. Solution: add a nonce.

To log-in, the client will first request a nonce (some cryptographic random sequence), generated by the authentication server. And the client must include the same nonce under the cipher with the password to log-in. And - of course - the nonce should only be valid once, so the authentication server must keep track of which has been issued and not yet received (and yes, you can have them expire too).

Now, if the attackers intercepted a log-in attempt, it won't be useful for any subsequent log-in because it won't match a valid nonce. If the attackers got a nonce from the authentication server, they won't be able to make the package again because they don't know the client password.


Ah, but a compromised server is a compromised server. Perhaps the attackers cannot get the passwords, but they can intercept the session IDs, and hijack the sessions. We could prevent them form inserting requests (e.g. using single use tokens), but they could still intercept and modify the ones the game server makes. So they could, for example, sell double resources to players.

By the way, most site that claim to give you extra rewards in such and such are fake. They are after gullible people.

For tamper protection we would use a hash. But the attackers can recalculate the hash on the modified request. So we upgrade to a signature with a private key. But the private key would be stored with the game server, so the attackers would be able to mimic that too. And for whatever other measures, the attackers could reverse engineer the game server and work around that too. Perhaps you want to use some obfuscation to make it harder. But there are no guarantees.

At least players are not sharing their password with the attackers… Or are they? If the attackers compromised the game server, and somebody gave them their password, they could modify that player data. Perhaps add some rewards to their account. And this might be enough to convince a fraction of the player base to share their passwords. There is no solution for people giving their password willingly.

I want to get across that even if we managed to protect user passwords in the case of the game server being compromised without being detected. It is not normal operation. You want to be able to detect the problem (be it from regular audits, from monitoring activity, from logs, from automated alerts, or whatever), and you want to be able to fix it (which requires a plan and preparations for that plan).

\$\endgroup\$
0
\$\begingroup\$

Servers talking to servers need to authenticate themselves to each other. And in order to do that, they need a secret (password or certificate). That's a pretty normal IT problem not limited to game servers.

The usual solution is not to hardcode the credentials in the sourcecode, but to put them into a separate configuration file read by the server at runtime.

If it is not too much work to implement on your technology stack, then I would recommend to use certificate-based authentication instead of password-authentication for server-server communication. It has the advantage that the database only needs the public key of the gameserver, while the private key remains on the gameserver. The less copies of the login credentials are around, the better.

Firewall rules which prevent any other IP address except the server IP from connecting to the write-enabled IP can be an additional measure as part of a defense-in-depth strategy, but I would not rely on that. The reason is that when the authentication system breaks, you will notice immediately. But when the firewall rules get deactivated for some reason, you might not notice anything until someone successfully connects to the database who shouldn't.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .