I want to explain my current situation:
I'm building a 3D parkour platforming game in which players race on seperate maps/levels and win medals by beating the time trials as fast as possible.
The game also includes a map-editor with which players can create their own maps.
Alongside the game i intend to provide a (master-)server which takles the following tasks:
- custom map uploading (so that players have a place to upload and share their maps)
- online leaderboards for the "official" maps and all uploaded maps on the server
- calculation of player statistics (number of medals, "ladderpoints", etc...)
I plan on releasing the game on steam (still isn't 100% set if it's going to be commercially or free, although i would love to use the opportunity and release it commercially to see how the "indie live style" would look like and if it's viable for me to do this as my full-time job in the future.) and thus it would be great if it would be possible to create "user accounts" on the master server for each steam-player who played the game.
The main purpose for the accounts is to allow the players to log-in on the games website and upload their custom maps to the central database.
(So that only players who played/purchased the game can log-in and upload custom maps.)
I already implemented a possible solution, although it has some issues:
After the start of the game the client connects to the server (via simple HTTP request) and sends the steam-ID of the player to the server.
The server then checks if the Steam-ID is already in the steam database. If not, the steam-ID is added to the database.
If the player is already registered, then the game attempts to log-in by checking of the saved password on the client matches with the one on the server (the password is transferred somewhat securely via hashing and a session specific salt which is generated at the login attempt.)
If the player registers at the first time, he recieves a "password" (generated by the server) which he can use to login on the website.
Now here is the biiiiiiiig problem:
The password is created once and stored as a local file on the client.
If the player looses this file, he will not be able to login anymore if he doesn't know the password which was generated by the server.
Even worse: What if someone tries to mess with the system and submits HTTP requests with random Steam-IDs to the server?
If a player starts the game for the first time and the steam-ID is already in the database, he/she will not be able to login as the password was already generated.
Those accounts don't have any kind data which can be used to verify the player (like an email).
To counter this problem i allowed the client to request a "password reset".
To do a password reset, the server has to generate a unique public "key" which is then sent to the client.
The client then hashes the steam-ID with the public key + a private key which is stored in the games exe. (The private key is stored on the client and server.)
The hash on the clientside is then sent to the server. If the hash is valid then a new password is sent to the client (like on their first registration attempt.)
The idea was that nobody is going to be able to submit simple HTTP requests to the server to registrate random Steam-IDs without the valid steam accounts.
Now the problem is that once the private key is figured out, literally anybody could request a password reset for every single account and login on the website... (i know that storing keys/passwords isn't really secure...)
I just want to prevent that "hackers" get into the accounts of other players and wreak havoc by submitting/spamming maps or change settings of the users account.
There are alternatives to this solution which came to my mind, but each of those has its own issues (mostly security wise)
- Steam Web Api - This would probably the easiest solution. The game would simply register the steamID on the server (if the ID isn't already in the database) but now password would be generated/sent to the client. Instead players would be able to login into their account on the website by using Steams OpenID system. The issue here is that i'm afraid that the data might be compromised. (Someone could either hack into the server and redirect the openID login onto a fake webiste or use a Man in the middle attack and redirect to a fake website from there.) It may be unlikely that this would happen, but i simply don't want to take the risk. Additionally i've read that steams OpenID implementation does violate some of the OpenID specifications and thus is "potentially" insecure (at least that's what i've read on some websites) however i'm not an expert in that field.
- Allow players to create custom accounts by using an email and "link" steamIDs with this account. This solution is much safer (the email would be the only "critical" user-information which is stored on the server) but the problem is that i can't avoid that players create multiple accounts and link steam-IDs which belong to other users. (This system wouldn't prevent duplicate/fake accounts.)
Now bare in mind that security of sensible userdata is on top of my priority list. Data breaches happen in this day and age. Of course i will make sure that everything is set up as secure as possible, but i simply can't quarantee that this never happens.
The simplest solution would be to remove the mapsharing idea completely and only provide leaderboards... (which don't require any kind of login...) althoug it would be nice to be able to provide that feature as each map (even player created ones which got uploaded) recieve their own leaderboard on the serverside on which players can battle against the best time possible.
Sorry for the long post. I know that it's a very specific issue.
I don't expect anyone to come up with an idea/solution (or even answer at all.) But maybe someone here as an idea or something to contribute to a possible solution. (Or even if someone who has experience with features/systems like this and who could share their knowledge.)