Non-SQL server database

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
knuxyl
Prole
Posts: 35
Joined: Sat Aug 13, 2016 4:40 am

Non-SQL server database

Post by knuxyl » Thu Sep 12, 2019 12:58 pm

I cannot seem to find any good server databases for use with love2d that do not require external components (like sql servers, etc).

I tried to setup FlatDB, but I'd have to rewrite the whole thing because it uses io.open/io.write. I tried switching the basics checks to love.filesystem checks and got it to see the directory in .local/share/love (im on linux), but that's as far as I can get.

Im building a multiplayer rpg (could be mmo, highly doubt it would get to that nor do i care) and I've already laid out how the game will function, so now I need to back to the foundation to make it multiplayer.

I am making a client with Single Player/Server/Multiplayer capabilities, and also a standalone server, similar to how minecraft works. I'm working on the server now. I'm using bitser for serialization and I have communication setup between a client and server. I just need to choose a database.

One concern I do have is amount of writes being done to a disk from the server. Should I setup a save interval every 5 minutes or so?

The database just needs to save tables/variables. Nothing special, no functions, etc.

I also have no experience with network security. I've read I need a salt and hash on user passwords but I have no clue how to do this. I could probably easily do a sha256 on the password before it's sent, but I'm worried about security because the game is open source. This is secondary atm after database, so I'll read up on this further but help in this area also would be great.

Thanks

User avatar
raidho36
Party member
Posts: 1860
Joined: Mon Jun 17, 2013 12:00 pm

Re: Non-SQL server database

Post by raidho36 » Thu Sep 12, 2019 2:08 pm

FlatDB seems like a good choice for the purpose. Just don't write it too often, once every few minutes - for rolling backup - is fine; beyond this you only need to save the data when you shut down the server. The io module is pretty reliable, I don't know why wouldn't you use it. LOVE can fetch working directory or save directory, and you can pass this in for file operations. Even so, FlatDB is only a hundred odd lines of code, it should be more than trivial to modify it to use PhysFS instead of IO. By the same token, it could be modified to do the rolling backup one file at a time rather than immediately storing the entire database.

Security through obscurity only lasts so long. That's why virtually every security protocol out there is completely open. It's secure because it's extremely difficult to crack even if you have all the information to do it. But if security hinges on the fact that no one knows how it works and otherwise is defeated easily, it's basically a dud - hackers love challenges and it won't be long before it's completely exposed.

To provide good security, you just have to NEVER communicate nor store real passwords. Put the password though a hash function (aforementioned SHA256 is suitable) then send this to server. Hashing is a good security for passwords because it's non-reversible and it's impossible to tell what the original password was. The same could be applied to logins, emails and other data. Emails however may not be hashed because you'd need them to send mail updates to the users; you'd have to encrypt them, but if your server has any way to decrypt them whatsoever, then whoever gains access to the server does too. At this point, encryption is really optional and the data can be stored as plaintext, the only security improvement to be had from encryption would be if a hacker somehow only had access to your database but none of the other files (particularly the file containing encryption keys), so they'd only get encrypted emails with no way to decipher them. Same argument applies to all data which server must know in unencrypted form. It goes without saying that you do not send any sensitive data over the internet in unencrypted form, which includes already hashed passwords.

User avatar
pgimeno
Party member
Posts: 1772
Joined: Sun Oct 18, 2015 2:58 pm

Re: Non-SQL server database

Post by pgimeno » Thu Sep 12, 2019 7:02 pm

knuxyl wrote:
Thu Sep 12, 2019 12:58 pm
I also have no experience with network security. I've read I need a salt and hash on user passwords but I have no clue how to do this. I could probably easily do a sha256 on the password before it's sent, but I'm worried about security because the game is open source.
Storing simply the hash of the password alone and using that for network communication has several problems from a security standpoint:
  1. Someone with a table of hashes can find out some passwords. There's this thing called "rainbow tables" which is a sort of compressed database of hashes. This is especially problematic for users who choose short passwords. I think there are some rainbow table-based online databases for SHA-256, where you enter a SHA-256 and it tells you the password.
  2. If someone uses the same password in two sites with the same scheme, the hash in both sites will be the same. This is minor, but it reveals the information that the passwords are equal.
  3. Two users in the same server with the same password will have the same hash. If an attacker breaks one, they have both.
  4. Spying the communication from the user to find the hash allows access to the game, even without knowing the password.
  5. Spying the communication at the time of registration allows future access to the game.
The first problem can be solved by making the hash different from the simple application of a hash function. One solution to problems 1 and 2 is to use a site-specific salt and encrypt the user password with a HMAC-SHA-256 algorithm using that salt. Simple concatenation for combining strings has its problems, hence why I suggest HMAC-SHA-256 instead.

There are hash functions specifically designed to be slow, like the bcrypt scheme, intended for deterring the use of rainbow tables and brute force searches. Not sure if Lua is powerful enough for that.

One solution to the third problem is to use a user-specific salt. That's a randomly generated string that gets stored with the hash, and necessary to check the validity. This salt can be applied through HMAC-SHA-256 again. However, this can have problems, so another solution is to use the username as salt.

The fourth problem can be solved with the use of a challenge-response scheme for password verification.

I know of no solution for problem 5, other than using encrypted communication to let the server know what's the initial value that needs to be stored in the database. TLS is OK.

In practical terms:
  • On server setup, server generates a site-specific random salt string.
  • To register a client:
    • Server establishes encrypted communication with the client.
    • Server sends server-specific random salt to the client.
    • Client calculates user_hash = HMAC_SHA_256(server_salt, HMAC_SHA_256(username, user_password)) and sends it to the server.
    • Server stores username and user_hash together with the other userdata.
  • To log in a client:
    • Server generates a random challenge string.
    • Server sends site-specific salt and challenge string to user.
    • Client calculates user_hash = HMAC_SHA_256(server_salt, HMAC_SHA_256(username, user_password)) like on registration, but does not send it to the server.
    • Client calculates login_hash = HMAC_SHA_256(challenge, user_hash) and sends it to the server, together with the username.
    • Server calculates HMAC_SHA_256(challenge, stored_user_hash) using the user hash saved in the database for that client, and compares it with the login_hash the client sent. If they are equal, the user is authenticated.
This scheme has the advantage that the password itself is never sent from client to server, making the client more confident that a rogue server won't steal their password. Login can even be performed without encryption.

The only vulnerability I know for this scheme, is that a rogue server can use the same server salt as another one intentionally, so that when a user registers, the login credentials (user_hash) for the other server are exposed, letting the rogue server's owner log in to the other server as that user. A possible solution is to use the server name as additional server salt when generating user_hash, similarly to how the username is used as salt.

One disadvantage is that, for password recovery, the server can't tell the client the password, therefore it has to generate a new one instead.

(edited a typo and make wording a bit clearer at a few points)
Last edited by pgimeno on Fri Sep 13, 2019 4:57 pm, edited 1 time in total.

User avatar
raidho36
Party member
Posts: 1860
Joined: Mon Jun 17, 2013 12:00 pm

Re: Non-SQL server database

Post by raidho36 » Fri Sep 13, 2019 2:00 am

Basically, design your system around assumption that security system is already compromised and attackers have access to the data. The same way as car safety features are designed around assumption that the car is already in a crash.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 5 guests