Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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.

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!")

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top