Ideas for Online High Score System

Hello,

I’ve been trying to figure out a way to implement an online high score system for my game in Java. I have tried JDBC, but I found out that my shared hosting server does not allow MySQL connections from JDBC.

My high score system only needs to insert and show 10 scores and names.

First of all, I understand that I can only make hackers struggle, but not 100% protect it. (Though chances are not so high that someone would want to hack into a small game)
So, now I’m here considering other options…

  1. Executing php script from Java to connect MySQL. Aside from protecting against MySQL injection, I am going to use ProGuard to make effort protecting against decompiles and set temporary password for insertion.

  2. Just writing on a .txt file. My concern is security. If this choice works, how would I increase the level of security?

Which way is preferred? Any thoughts are appreciated.

Personally, for security I like the first option best. I’ve used php and Java, but never together, so I don’t personally know off the top of my head how to implement this, but I am sure you can find something easily enough.

However, if it were me I would just use the .txt option and not bother about security at all. Then if later it turns out to actually be a problem and people actually are hacking into the high scores list, then I’d change my implementation. This is mostly because I am way lazy though. It really depends on how popular you think your game is going to be.

You should probably not take my advice here. :stuck_out_tongue:

Keep it simple.

Go for the textfile first. You probably dont need database functionality when only using a highscore.
(only adds more work and potential problems)

Important is that the php handling the inputparameters propperly (look up php security for that)
and that you add some verification into the send scores, so someone can not easily manipulate the scores by
manually sending one.
For a small game some simple checksum procedure might be enough to avoid most simple “hacks”.
The hacker would have to decompile your game first to figure out how to manipulate the scores.

To be really save you would need a propper account validation system,
so you could erase manipulated scores (and users)

-> make a log of send scores!, dont just directly isert/replace them in the highscore,
so you can (if needed) manually revert back to the correct entries.

I’d go for a web language of your choice (I’d favour python or perl, but php would be fine) and a database backend. Then submit and fetch high scores over simple http requests.

A simple database is easy to set up, and it saves you having to deal with concurrent updates/modifications (which is a bit of a pain if you’re just using a file on your server).

Thanks guys.

At first, I thought of .txt file as an option, but I will exclude that. First of all, it’s not how score system is supposed to be done. It will also teach me some lessons.

I will go with php/MySQL solution.

I’m trying to come up with a way to prevent people just accessing the url and submitting fake scores. If someone decompiles my code, they will find out the url. Even if I set up a constant password in Java to send to php script, they can see that although it’s better than nothing. The sum check would also be found in the decompiled code. ProGuard will help me make it slightly harder, but I think it’s still not enough. It might be enough for this game, but I want to learn how to raise security level (again, I understand it’s impossible to make it impossible).

I have searched around to get inputs, but not successful, yet. A replay of game events is not an option for me. Aside from complexity, I think it will consume execution time.

Any suggestions to increase security level?

I rather imagine sqlite would be more than adequate to record high scores, no need to have another moving part with a separate mysql db.

Anyone determined to send fake score data can do so, and there’s really nothing you can do about it other than move all your game logic server-side. Even then someone could automate the game with a bot, though that’s a harder problem, most people won’t bother with it, and you should take it as a good sign of popularity if they do.

That’s true. Well, I will be monitoring the table anyways. I will manually delete fake record if I see any suspicious.

I have never used SQLite, so I just read about it. http://www.sqlite.org/whentouse.html

The only possible issue I found would be the concurrency. It says that the database locks reading/writing when one is in process. Though it says the lock would last for a few dozen milliseconds at most usually. I guess I shouldn’t consider this as an issue for this case since there won’t be that many people.

All I need is fetch, insert, and delete of a record. So I think I should consider SQLite as my solution, now.

But I do want to add some kind of protection in the code at least protecting from modifying the score board by just passing scores through url.

You can put and probably should put in some basic scrambling just to protect against casual score spoofing, but anyone determined to find the key will still find it very quickly. It’s literally impossible to solve unless you control everything down to the hardware of the client.

[quote=“sproingie,post:8,topic:38452”]
Or, somehow you submit a replay of the high scoring game to the server, and validate it somehow (ghost racers in a racing game are a good example).

However that involves running a headless version of your game on the server. And having a deterministic game so you can play it back and get the same result on the server. And people can still cheat if they can make a ‘perfect’ game recording.

Basically it’s a lot of work for very little gain. I’d just put some basic protection like a checksum and leave it at that.

One easy extra step can be to make only certain scores possible legitimately. Many arcade games do this where the smallest amount of points you can get is (say) 100, but you get 1 point when you use a continue. That means you can look at the high score table and see that a score of 235005 used five continues to get that. If you only allowed (say) scores that are a multiple of 3 then most casual hackers won’t notice and will probably submit an invalid score.

People who cheat usually aren’t subtle - they’ll give themselves a score of 99999999999999 and forget about it after a week. So maybe think about a moderation tool where you can block IPs or user names, or at the very least easily remove obvious cheated scores.

If it’s android game, you can use Scoreloop or Swarm.

It’s for a desktop game.

That’s right. I should know the score limit one can get, so I can set that if statement in my script.

I have some questions for the script.

I was going to do queries to check whether the score is to be saved or not. For example, I need to find and delete the lowest score to add a new higher score if the score board is full. (assuming I’m only keeping the top 15) I could do sort query to keep the scores sorted at the DB level every time I insert a new score. Else, I could do the sorting/determining score insertion after fetching into array. The latter would do more on php code to keep the SQL statements to minimum. Since reading/writing at the same will lock the table, I think doing less queries is important even though we might be talking about milliseconds.

Which of these 2 ways is more efficient for SQLite?

Just log the high score reports into your database, and do all the sorting and filtering and de-duplication logic with a query. Your inserts will be faster, and if you screw up somewhere, you can just fix the query and none of your data will be lost or corrupted.

I see.

So a replay on server side solution can be cheated if someone copy/paste the decompiled source code and make the game easier(obfuscated code gets tough though possible to cheat). It would also break through checksum. (if I’m not misunderstood)

Isn’t SQLite too vulnerable because it doesn’t have password? If someone finds out the url to the database file, he can access it from anywhere. I understand that the point we have been discussing is that hackers will find their way if they want to.

How can checksum be implemented in this case? Can you give a brief explanation or direct me to a link?

Scrambling would be for example, when sending the player name/score from java, the order of string is shifted by pattern and when receiving from script, shift them back?

The database must not be accessible from the web. Your code accesses it, nothing else.

You post the player name, score, and checksum(player,score,secret), where secret is some bit of data you bury in your code, however cleverly you want. The server also knows this secret, so it runs the same checksum function, and if they don’t match, then something is wrong.

Something like this would suffice. The secret here is really weak, but any string you compute will work as long as it’s constant or otherwise fully deterministic on name and score.


String makeChecksum(String name, int score) {
  return org.apache.commons.codec.digest.DigestUtils.md5Hex(name + score.toString() + "mysuperseekritword");
}

This is all security through obscurity, but every fancy version of this is just a variation on the same thing, just with trickier and trickier ways to establish a shared secret, up to and including running nearly arbitrary bytecode (which is how the java-based BD+ copy protection scheme works)

What about if they write their own code to access it? File location is all it needs to open connection, right?

sproingie,

Thanks a lot for your consistent replies and advises. I integrated the apache commons codec library into my java project.

If the database is not in the web-root, nobody can access it from the web.

Right, but how would I connect through my Java program in that case?

Running the java app on the server, connecting to the file, outside the web-root :persecutioncomplex:

If your server program is Java, I would recommend h2 or hsqldb. Last I looked, your server program was PHP, which comes with sqlite support in most builds. Your java program does not access the database directly, it talks to a server program that itself accesses the database.