Socket.io Security issues.

Started by
2 comments, last by Awoken 7 years, 1 month ago

For my project I'm wanting to use socket.io. K, sorry for asking such a general question, but I really have zero idea of what security risks there are using this library. Can anyone point me in the right direction to begin learning how to make it more secure, if it needs to be secured in the first place.

Another question, where can I find out more information about collecting and safely storing user data such as usernames and passwords for registered users on a website I'd create for a game?

Advertisement

For storing usernames and passwords use an encrypted connection (TLS connection), and once you receive the username and password store the username, but only store the encoded ('hashed') password. Currently bcrypt is the commonly recommended encoding library. When they log in again, use bcrypt on their password and compare the results with the previously bcrypt-ed results stored in the database. The bcrypt library requires a 'salt' value which is unique to every user. There are many good articles online that can show you how to create good per-user salt values.

Next is validating data. For commercial games this is even more important that hobby games: the networking code needs to assume all data is potentially wrong, corrupted, or an attack. Defend against it by validating EVERY value. Validate that positions are correct, validate that strings are the expected length, validate that command numbers match what they should be, validate that enumerated values are within range, validate EVERYTHING. An encrypted connection is not enough, since attackers have ways to connect through an encrypted connection but still send wrong values.

The socket.io library itself may have bugs, and if you use it, you may inherit those bugs.

Then again, the TCP implementation in your kernel may have bugs, and if you use it, you may inherit those bugs.

socket.io is more commonly used than any random networking library, so it's likely to be better-debugged than any random network library (and probably better-debugged than your own.)

Developing with socket.io isn't really that different from developing with regular web protocols, or with straight sockets.

The most important thing to pay attention to is making sure that you don't just trust the data from the client. If the client is in a pre-login state (hasn't yet had name/password validated,) then don't accept any gameplay requests. Remember which client was authenticated for a particular socket, and don't accept requests trying to claim they're another player. Don't do fancy things like passing functions or text to eval() over the protocol -- this leads to security problems for sure. Stick to basic data; numbers and strings and bools and nulls, and objects/arrays that contain only those things.

When time comes to mutate the database, don't expose a protocol that says "read database X" or "write database Y." Instead, expose functions that are specific to your game, like "get the list of gem inventory items for my character" or "consume 3 cords of wood to make a pile of charcoal." Don't try to be "smart" and pass in things like names-of-fields or names-of-tables in the protocol, so the user can substitute their own names. The dumber, the better. Use prepared queries and parametric arguments for your database access: Use ("update foo set bar=:value", {value:argument}) instead of "update foo set bar="+argument.

Finally, as frob said, when a user registers, and you receive email and password, call scrypt() or bcrypt() on the password, and store the output of that function in your database. Require passwords to be at least 12 characters long, and accept up to 255 character long paswords. Require that the password is not a subset of the email address, or vice versa. Don't have other password rules, except possibly "requires at least one space and at least one non-space character." Make sure the registration page runs over HTTPS. When the user tries to log in later, verify the password they provide you using the scrypt/bcrypt verify() functions.

enum Bool { True, False, FileNotFound };

I appreciate the feedback from the both of you. Specific and precise along with easy to follow.

This topic is closed to new replies.

Advertisement