views:

41

answers:

3

I know this is impossible, but how close can I get?

I'm creating achievements, and when a user 'gets the achievement' his browser tells him with a javascript popup, and sends a message to the server to update his profile.

I'd rather not have my users be able to just hit the webservice and get all the achievements. Signing the requests with a private key is better, but it would have to be stored in the .js file and then easily sniffed. I could obfuscate it, or do a unique one per user. And timestamp the requests.

Any better suggestions?

A: 

Well the problem is, how do you determine when someone has an achievement? If it's client side, something like

quest.hasGoldenRod = true;

Then yeah, you're going to have trouble stopping them from setting that themselves.

The way to do it is to have the server mirror the actions that the client takes to ensure they actually got the item legitimately.

Then, when the client says 'I got it', the server goes 'Let me check that,' and if it can also validate that the client did indeed get it, then all is well and give them the achievement.

Noon Silk
Interesting. Lets say the achievement is "typed the word paul into a text box", then the server can't emulate it. It can know that it gave the user a search box, but can't know the action
Paul Tarjan
On the other hand, you *can* send the contents of the textbox to the server and have it check to at least make sure it matches the word.
Amber
Re the 'paul' situation, you repeat the action. You do it on the client, and you send the same instructions to the server. Then you ensure they are in the same state.
Noon Silk
A: 

As the original question acknowledges, I think this is basically impossible in situations where it's really hard to get the server to rerun what the client did. (eg. a platform game with close timing)

Obfustication's probably your best bet. First off do a bit of crypto and include timing information - use public/private key per user. That gets rid of the basic traffic sniffing/replay. Obfusticate the client code too so they at least have to put some effort into decoding it. I'd say that'd probably eliminate 99% of the people trying to cheat. Until that last 1% writes a firefox add-on to unlock achievements and gives it to the other 99% at least.

Beyond that, well, don't have achievements reward them with anything important.

  • Colin
Colin Coghill
A: 

Signing doesn't help you. You have two approaches:

  1. You can go for complete verification. The only way to assure this completely is to involve the server, like silky said. If the achievement is that the user got to some "area" in a game - the game sends a "Hey I got to LA!" and you go "I know you did. You've been telling me all along as you enter each new area, and I've been keeping track."

  2. You can go for "reasonable" verification using techniques like obfuscation and timing. Have the server send a calculation function userEarnedGoldBarAcheivement down to the client that is the test function - and the function changes slightly every day (so if you send me a request with {goldBar: true, key:12345} I go "Uh, uh, that key was yesterday's!")

Tom Ritter