Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Server-side highscores for a Javascript-written game

I'm implementing a simple game in Javascript, and am interested in having an online highscores table for it, so that players can compete against one another. I've two concerns about this:

  1. What is the simplest server-side program I need for this purpose? I don't need a full-fledged "web application", just something simple that gets POST requests with highscores, updates a database and sends back lists of scores. I'm familiar with Django. What are your suggestions?
  2. How can I make the highscores table reasonably secure? I'm aware that making it bulletproof against competent and dedicated hackers is difficult, but I wouldn't want anyone with access to the Javascript sourcecode to be able to submit fictitious scores too simply. Any tools for this purpose?
like image 312
Eli Bendersky Avatar asked Feb 19 '10 15:02

Eli Bendersky


2 Answers

It's going to be pretty hard to secure the high scores. I mean, it's not enough to ensure that it comes from your page, because if, say, the JavaScript function is submitHighScore(n) then they can always type javascript:submitHighScore(10000000) in the address bar on that page and have it work.

What comes to mind is perhaps some sort of hash function that generates specific codes that match certain levels in the game. When submitting the score it would also submit this hash, so users would have had to get to this level in order to get that equivalent score.

Another option would be for the game to pull in some kind of key that only works temporarily, so as you went along the key would change and then the score would be submitted to a central server intermittently.

Keep in mind that really determined individuals can always just track the data being sent to your data and decompile it.

You could go the Broderbund route and ask the player trivia questions which are validated server-side to ensure they really did pass the level they said they did...something like "What color was the monster in the previous level?"

like image 149
Jordan Reiter Avatar answered Sep 30 '22 14:09

Jordan Reiter


To submit score securely, sign it (you'd also need to ensure that the score isn't faked before it's signed and sent, but that's another problem).

Hide a secret in JS code, and send highscore + hash(highscore + secret) to the server. The hash could be MD5/SHA1 — there are easy to find JS implementations.

Of course it won't stand anyone carefully analysing the JS code, but at least someone won't be able to submit fake highscore just by tampering with HTTP traffic.

On hiding stuff in JS:

You can't really hide it (it's ultimately futile like DRM), but you can try hard to obfuscate it and make debugging painful.

  1. Don't put the secret as a literal in the source code - compute it at run time combining results of several functions, local and global-ish variables.
  2. Minify all code, remove sourcemaps.
  3. Add bits of code that don't do anything, but seem to be important, to make debugging more confusing.
  4. Don't put anything in global scope, but do rely on shared mutable state by passing closures and arrays around.
  5. Rely on Date and timers to cause race conditions to make your code produce wrong results if it's paused in the debugger (just don't make it too tight to allow it to run on slow machines).

If the game is deterministic (like a puzzle game), then users could submit highscore in form of a log of steps taken to win (user's input) that you'd replay on the server to calculate the score.

This would change attack from finding/emulating score-submitting function to witing AI or hacking the game itself to make it easier to play (but still within its basic rules).

like image 24
Kornel Avatar answered Sep 30 '22 14:09

Kornel