Okay, someone tasked me to make a leaderboard for their game. However, the one I have right now is really insecure. All it does is check if someone is in the top 100, and if they are, post the score to the server, where the server will completely trust the client to give a real score.

My question is: How would I make it harder, or better, impossible, to send a fake high score, because right now they can just post a value to an easy-to-find endpoint.

Clarifications: The game is running in an interpreted environment, therefore obfuscation is not practical, and the game has a lot of input (an hour's worth at least), so sending that to the server is also impractical.

  • 1
    \$\begingroup\$ @congusbongus added some more specific details, because I didn't find any useful answers there for this situation. =) \$\endgroup\$ – Shien Feb 2 '15 at 7:04
  • 2
    \$\begingroup\$ My answer to this question is exactly the same as answer to another question. In short, you need either a "proof of work", or implement critical parts of the gameplay on the server. Any other ways are insecure. \$\endgroup\$ – Lie Ryan Feb 2 '15 at 12:28
  • \$\begingroup\$ "Clarifications: The game is running in an interpreted environment, therefore obfuscation is not practical, and the game has a lot of input (an hour's worth at least), so sending that to the server is also impractical." i.e. you want it to magically work. Uh. Not going to happen. \$\endgroup\$ – o0'. Feb 2 '15 at 14:09

Scrambling the transmitted score is probably worthwhile.

To avoid cheat-engine type stuff, you can always scramble it in memory too. If you're storing seven variables, each of which, %10, is a digit, and you add a random number of 10s to each variable whenever a score changes, then it will be tricky to find a variable that matters. You could also get quite silly with that, by having certain values of the multiples-of-ten be illegal, and affect the score in "special ways", or send a signal to the server "this player is messing with the scores".

But most importantly, you should do what you said you cannot do, and send gameplay progress.

Sending every keystroke is not infeasible (MMOs do it!), but it would require storing a state machine of each game serverside. So, simplify.

So if it's, say, a platformer, then you have it send what level they are on, and a notification each time they kill a mob. You then validate that by saying, you know their weapon can kill at most 4 people, and fires once every second. Then if they claim to kill ten people at once, that's not legit. If they claim to kill more people than are on their current level, it's not legit. If the mob ids they send with their kill are from different rooms and could not be simultaneously killed, that's not legit.

Don't accept a score that's jumped infeasibly high in one go.

But, it's the internet, and lag happens, so you have to allow a certain flexibility in timing.

What if it's, say, a racing game? Well, you can give checkpoint timings. You know the car specs, you know its max speed, max acceleration, you know the min distances between checkpoints, so you can calculate the min possible time (allowing a little leeway for speeding up by getting hit from behind, powerups, etc).

So you avoid the "999999points" obvious hacks, and instead, they have to submit a while BUNCH of packets, saying "lap 1 done in [theoretical best time]", [wait a bit] "lap 2 done in [theoretical best time]", ... "end of race", "prize money spent on buying [upgrade] to improve theoretical best time"... improving each time.

Essentially: split the game down into gated waypoints, send what metadata you can validate serverside, and write logic that accepts or denies based on that.

This is a serious and hefty way to tackle the problem, and you should only do as much towards it as is worth. for a free online web game, just prevent the most obvious all-nines scores and be done with it. For a for-pay game, it's worth taking it further, depending on how core a game mechanic the leaderboards are.

| improve this answer | |

If what you get is just a score number, you can not verify how it was achieved.

To make it more secure you need to obtain a full replay and verify that the game was fair (no cheats used, no score hacking). One of possible implementations of this idea is keeping the game on the server. If all logic is on the server and player can only send his actions, then you can be sure, that there was no cheating. Of course that leaves exploitations of game bugs. You decide "if" and "how" you need to cope with those.

| improve this answer | |

You are right that there is risk in just letting a player post any score they want. That said, it will be very hard for you prevent cheating, as long as the player is playing offline and on their own machine. If the game is online, and your server is calculating all scores, then you can safely store the score, since you trust how it was calculated.

There are some things you can do to slow down the easy hacks though. Here's one suggestion...

Require users to register online with you before they can post to a leader board

  1. Internally with your game, have a stored/permanent "user registration ID" value. This is initially blank.
  2. If a user wants to post to the leader board and the registration id is blank, they must register first.
  3. Registration is done from inside your game.
  4. Game sends registration request with user's desired name.
  5. Your server validates the name (is it unique for example?)
  6. Your server allocates a new registration ID (something like a UUID (look it up)) and sends it back to the game.
  7. The game stores the registration ID internally for future reference.

Encrypt the score before you send it, to make it harder to submit fake scores

  1. When the game sends a score, it encrypts the value and sends the encrypted version of the score, along with the registration ID of the player. It does not send a direct score value as an open number!
  2. Your server decrypts the score value, and registers the score.
  3. You will need to store the encryption key inside your software, which potentially could be hacked.

PS You might check out https://stackoverflow.com/questions/25999/secure-online-highscore-lists-for-non-web-games for a similar question and answers. Also http://gamasutra.com/blogs/PriyadarshiChowdhary/20141121/230744/Design_and_safety_tips_for_leaderboard.php for an article on the subject.

| improve this answer | |
  • 2
    \$\begingroup\$ "Encrypt the score before you send it, to make it harder to submit fake scores", I don't agree with you. This may prevent people from sending fake scores to the API (if anything) but wont prevent people from hacking their score inside the game in the first place (e.g. cheat engine). \$\endgroup\$ – angarg12 Feb 2 '15 at 7:04
  • 4
    \$\begingroup\$ Nope it won't. All you can do is make it harder. It's basically a very hard problem, and unless you have your server manage the game and decide the score, it's impossible to validate the score submitted to you. \$\endgroup\$ – Tim Holt Feb 2 '15 at 7:31
  • \$\begingroup\$ @TimHolt not exactly. It's an impossible problem, and the only real solution is to do it server-side. Other pseudo-solutions are less than a placebo. \$\endgroup\$ – o0'. Feb 2 '15 at 14:11

To make this happen you must ensure that the game is always online. it has pros and cons also.

This is only method by which you can ensure validity of score.

at login time validate the score from server and when connection breaks store the last score made by user and next time he logins to the server update and match the score from server.

| improve this answer | |
  • \$\begingroup\$ This is absolutely wrong. Just being online doesn't imply anything. Either the game logic is server-side, or you could be offline as well. \$\endgroup\$ – o0'. Feb 2 '15 at 14:12
  • \$\begingroup\$ without being online u cant check the validity.. every offline game is cracked. you any offline game which is not cracked \$\endgroup\$ – Dalvik Feb 2 '15 at 16:05
  • \$\begingroup\$ Again, and for the last time: the sole act of being online guarantees exactly nothing. It is just one of many required features. \$\endgroup\$ – o0'. Feb 3 '15 at 10:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.