[web] Game client - mySQL db communication

Started by
5 comments, last by dinojazz 14 years, 5 months ago
I'm currently working on a small game project and want to provide user statistics in a web frontend for the users. Getting the web/sql part done is no big deal but I'm having some trouble figuring out how I'd want the game client to transfer the data to the statistics server in a more or less secure way. I certanly don't want the client to directly insert sql querries but let it probably access a sort of incoming.php with parameters in the url to hand over the data. However, I still don't know how to make it at least a little secure so does anyone have any suggestions? SSL is no option by the way. :( Any kind of advice would be appreciated And sorry if this is in the wrong forum category, not sure where else to put this instead. - Lili
Advertisement
Quote:Original post by Lilithia
I'm currently working on a small game project and want to provide user statistics in a web frontend for the users. Getting the web/sql part done is no big deal but I'm having some trouble figuring out how I'd want the game client to transfer the data to the statistics server in a more or less secure way.

What does the client use to communicate with the server? JavaScript, Flash, regular form posts?
And against what does it need to be secured? Submitting incorrect or malicious data, bogus requests made from outside the game?
Quote:I certanly don't want the client to directly insert sql querries but let it probably access a sort of incoming.php with parameters in the url to hand over the data.

Sounds okay.
Quote:However, I still don't know how to make it at least a little secure so does anyone have any suggestions?

What you at least want to do is check all the data first before you commit it to the database.

For instance, lets say we are running a RPG that allows a player buy an axe with his gold. And lets assume we call a page called buy.php with a parameter telling us which item to purchase, ?item=23

Among the things to check might be the following:
  • Check if user is logged in (session state)

  • Check if item to buy exists in the database

  • Check if user doesn't already own an axe

  • Check if user is allowed to buy an axe (perhaps this depends on his skill level or something)

  • Check if user has enough gold

  • Etc..


That's where it all starts. On a non secure connection, you'll always be able to track the submitted URLs. You could obfuscate the transmitted query string, but will be trivial to decode.
The game client itself is written in C# and there is no login at all. Every player has a unique (permanent) ID but thats about it whenit comes to identifying users. The game is pretty much completely done, too. The statistics system is just a little extra thing I want to add. But well, the problem is "how" to transmit the data from the client to the stats server

("how" as in how to make it somewhat secure .. the technical aspect of getting the client to send something over with http for instance to the server is not the issue)
If your statistics server is web based, you'll have to send them to a page like you said incoming.php with parameters.
However, the security issue you will encounter is the authenticity of the submitted data. (a user can't compose the URL by hand and put it in a browser).
So basically you should find some sort of encryption on the client side for the parameters and then decrypt the data on server and update the mysql tables.
Quote:Original post by Lilithia
Getting the web/sql part done is no big deal but I'm having some trouble figuring out how I'd want the game client to transfer the data to the statistics server in a more or less secure way.


What you need is input validation, maybe input sanitation, and proper escaping of values which are to be inserted into SQL queries. Security basically means that you must be paranoid very careful about your input data.

A relatively secure way is to first validate your input data against basic data types. For example, if you expect some input variable to be a number, and a string with non-numeric characters comes in, you can be sure that it's either a bug in your client or a hacking attempt. Either way, the best way to deal with malformed input at this stage is to discard the message and return an error code.

Second (this step is optional-ish, if you do the first and next step right), you clean (sanitize) the input strings. That means, removing any invalid input characters. This won't make much difference for non-string data, though, if you validated in the first step, but it can help with step three.

Third, you'll need to escape the input data, especially string input, before inserting it into any SQL strings which will eventually be run on your server. This counters the threat from forged string input which could contain escapes (\0 characters, quotation characters) to run arbitrary SQL. There are functions in the MySQL client lib for escaping values.
if it were me, then i would probably sanatise/escape any incoming strings, also I would definately concider including some kind of checksum hash with the submit. If the checksum doesn't match then throw the entire thing away.

UserId=1234567&FirstName=John&LastName=Doe&HighScore=2000&checksum=(SHA1(FirstName + LastName + HighScore+ UserId + "salt"))

perform that same operation on the server, and if the hashes don't match then ignore everything. Not 'secure' but between that and sting normalization it should probably suffice, protecting you from run of the mill sql injection attacks and lazy hackers. but anybody with a decompiler and some time to waste could probably fabricate a illegitimate request.
I would recommend a form that has a hidden input field called "validrequest" the value of that field will be filled by an algorithm that you make. Let's say your secret algorithm works like this the first two figures are the current month number (with leading zeros) the last two are the hour of the request (with leading zeros 24 h time) and then in the middle you have a number that operated with mod(%)7 function always results with number 1(or to make it more complex the day of the month). It's no big deal to make something like this.
Why this and not hash of certain data? because in the way I propose the solution a user will be time dependent and request dependent as you check the first and the last two letters to coincide with the current time on the server, meaning that a request used today will only work tomorrow at the same time (or next month at the same time, in the second case). So what if a user makes a request at 23:59 and presses the report button at 00:01? No problem, just tell him that his request has expired, and that he should try again.

This topic is closed to new replies.

Advertisement