views:

191

answers:

2

I'm working on the backend for a Flash game and I need to secure the data going into the scoreboard.

The game is going to be hosted on many sites in a banner ad, the user will play the game in the advert then click through to the main site to save their details.

At the moment I am thinking along the lines of this

  1. User plays the game and clicks to submit their score
  2. In the background, the banner sends the score and the originating domain to a script on the main site.
  3. The script check the domain is one of the valid domains the ad is being hosted on.
  4. If everything is right, the script creates a hash of this score and domain and stores it in the database along side the score.
  5. The script returns the hash to Flash which cobbles it onto the querystring of a getURL which opens the main scoreboard
  6. The scoreboard page checks the referer to make sure it is one of the valid domains.
  7. If it is it then checks the database for the hash to if it's a valid token
  8. the user then fills in their details and the record is updated based on the hash

Last time I checked FLash doesn't send referer info, which kinda throws a spanner into my plan. So, is there an already established pattern for this kind of Flash/Database interaction?

What sort of Hashing/Checksuming should I use in step 4? What is the correct name for this kind of operation, is it a hash, a checksum or something else?

I understand that being a clientside technology, Flash will never actually be THAT secure, but in my mind, something like the above is about as dificult as you're going to make it to hack this kind of application.

UPDATE: My main objective is to make it harder for people to find the URL of the script that adds the score to the database and simply spam it with fake scores.

Thanks, Greg

+2  A: 

Essentially you don't want to verify the score is coming from a legit client, you want to verify the client actually played the game to achieve the score. Essentially the best you can hope for is people being required to create an AI to play the game.

Here are a couple things you can try:

  • Log the inputs into the game and send those along with the score. The server can then validate that the score corresponds to a possible game. You can also detect duplicate submissions this way.
  • Apply rate limiting to stop clients from submitting scores at an obviously inhuman pace. Apply upper limits on the allowable scores based on what is actually possible to achieve and lower limits on things like actions per second.
  • Use previous inputs to partially seed the pseudo random number generator (assuming you use one). This makes it less likely that clients can alter a submission slightly and still get a valid game/score combo.
Strilanc
+1  A: 

I have previously worked in the game industry, and did something along these lines. To my knowledge, no one ever bothered cracking the score submitting part.

The way it was done was :

  1. Generate a random number as a salt (from flash)
  2. Encode the score using math operations, based on the salt (from flash)
  3. Add a checksum to make sure there was no tempering on the score (from flash)
  4. Send the score and any required data to the score submitting page
  5. On the server, validate that the score has not been tempered using the checksum
  6. If the score is valid, then insert it into the database, else, reject it
  7. If you want, you might log ip adresses of the submitters of scores violating the checksums (maybe a policy of three bad checksums, you're out) and add a script to ban them from accessing the server for 1h, but this will probably not be required unless someone wants to crack your code that bad.

Note : The hashing / checksuming was made using a custom function. Did not need something very secure. It was made using a computation on the salt and the score. Some simple math operations like sums, multiplications and subtractions.


Edit: a simple algorithm / maths for the checksum

Lets say your user has a score of 5885.
You generate a random number as a salt of 134789 (constant length, pad with 0)

cryptedScore = Score * Salt (you should use something a bit more complex here, but it is just an exemple)

In our example, the crypted score would be : 793233265

Now for the checksum, lets say you want to have a value of 253 as a checksum.
You add all the numbers of your crypted score 7+9+3+2+3+3+2+6+5 = 40

Now, you calculate the value of your checksum for this score
253 - (Sum of crypted score numbers % 253)

Now, we have the following numbers:
the salt = 134789
the crypted score = 793233265
the checksum = 40

You make a request to the server, sending 134789793233265040 as a score.

On score server, you can divide 793233265 by 134789 giving 5885 and validate the checksum using the same function as before.

If the checksum fails, then numbers have been tampered.

you could probably end up with something much more secure, but it should do the trick.

Martin
Cheers Martin, Do you have any links or example code for the checksum function. Cheers
Greg B