4

I've a game in which my JavaScript calls PHP scripts via POST to change values in the database. How can I prevent someone repeatedly duplicating the request and giving themselves a billion points?

Right now I pass a password through sha1() and check if it's there on the PHP side, but this wouldn't stop someone repeating the request.

I can't use timestamps because time will lapse between call (JS POST request) and run of the PHP script.


Edit:

  • My PHP script doesn't increment the database values (points=points+10), it takes the values passed to it and updates the field (points=300)
  • I update several tables on each interaction (well each interaction which result in points going up) in the game. One of these keeps track of every vote. This table only allows a user to vote on any image once. If I were to do this update first, if the user has tried to repeat this request, the result would return an error and I could kill the PHP script.

Is this sufficient security? Do I still need to worry about preventing duplicate requests?

Community
  • 1
  • 1
Adam Lynch
  • 3,341
  • 5
  • 36
  • 66
  • 1
    there is a similar question here: http://stackoverflow.com/questions/2543881/how-to-make-a-secure-game-in-javascript the answer is basically no way is possible. – longstaff Sep 05 '11 at 09:08

5 Answers5

2

It sounds like a lot of this logic now remains clientside, so you can't stop someone from sending "score.php?score=1000" multiple times.

Add logic to the server side that checks how often a given request can be executed, or, even better, execute game logic completely serverside (so the user won't have to submit his own score, but simply requests a certain game action to be executed, eventually resulting in a score which could then be added to the user).

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • 1. That's GET, not POST but I get what you mean. 2. I don't want to do the action at the end because if the user is doing badly they can just reload the page and that round is forgotten about. – Adam Lynch Sep 05 '11 at 08:39
  • I'm sure you know @Adam but regardless of GET or POST both can be easily done by the client. – Kenny Cason Nov 18 '11 at 20:45
1

If you have some form of session identifier you can increment a count of times that request has been made. This isn't bullet proof however, clearing out session cookies will allow that request to be made again.

You will need some form of login to prevent someone clearing their cookies, or even a cURL script looping.

Edit:

As a stop-gap measure, you could add a form of CSRF protection, a one-time-use hash would need to be applied to each request to make it valid.

cloakedninjas
  • 4,007
  • 2
  • 31
  • 45
  • A CSRF one-time hash would be good but how could the PHP side know what to check it against? Timestamps won't work – Adam Lynch Sep 05 '11 at 08:42
  • 2
    It would be saved in the session - and every request would return a new one that can be used in the next request. – ThiefMaster Sep 05 '11 at 09:18
0

You can also pass a flag from post which you can set to whatsoever value when u really wants to update the value in database otherwise set it to 0. And while updating check the value of the flag and corresponding update it.

Astha
  • 1,728
  • 5
  • 17
  • 36
  • When you say update it I'm assuming you mean this value will be different on every request? What could the value be? and how would the PHP know what it would be in advance? – Adam Lynch Sep 05 '11 at 08:49
  • no, what i was saying is when ever you store a value in db u calculate it some where right? then you update it in db, so there u can set the flag for the value lets say 1 and can check after post its value. and after storing it in db again set that flag to 0. So in this way after updating db flag will be 0 again and no duplicate value can be entered. – Astha Sep 05 '11 at 09:55
  • My calculation is done in the JS and the SQL update is done in the PHP. Couldn't someone use Firebug and duplicate/hack that? Or if I moved the calculation to the PHP script then they could easily just duplicate the request – Adam Lynch Sep 05 '11 at 09:59
  • (as u edited you question)if its just a duplicate entry not the incremental one you can have a check on the php page for that. If the same data already exists dont update it otherwise do – Astha Sep 05 '11 at 10:23
0

given that GET or POST both can be easily done by the client. if you are just sending a raw score to the server this can never be good. I have never written a game where that much logic occurs on the client. the client side should just send commands to the server and the server decides whether or not this is a valid transaction/state. more or less the server knows the state of the client and the client just reflects that. that's the probably the only true way to gaurantee that what a client is doing is legal.

Kenny Cason
  • 12,109
  • 11
  • 47
  • 72
-3

Use captcha Wiki CAPTCHA , reCAPTCHA

Also, use Session to write down number of repeated requests done my user to the server and increment it on each successful request,

Then block the user from accessing your PHP script with the help of session storage data. PHP SESSIONS

Pawan Choudhary
  • 1,073
  • 1
  • 10
  • 20
  • A captcha interrupting the game on every database interaction? That would ruin the experience. Not completely sure what you're saying about "`number of repeated requests`", could you explain? – Adam Lynch Sep 05 '11 at 08:47
  • ie. make a `$SESSION['number_of_request']` , then set the `$SESSION['number_of_request']` default to `ZERO` and then increment it on each successful request the user made, if you think that the user made many request to the server very often then by PHP's `if` statement block his access to your script, and also you can flush your session after every x minutes or hours :) – Pawan Choudhary Sep 05 '11 at 08:58
  • but the user could just clear the session? and it would allow them number_of_allowed_interactions-1 spoofed interactions – Adam Lynch Sep 05 '11 at 09:56
  • user have no control over sessions, they have in case of cookies – Pawan Choudhary Sep 05 '11 at 14:06
  • well I'd need to assign the session variables by calling a PHP script right? well they could duplicate that and then the actual request to give them points – Adam Lynch Sep 05 '11 at 14:11
  • if you have a database, then give each user a unique `id`, add a column named as `number_of_request` and then write your session data to it. btw user cannot duplicate session on their own, however they can use another browser to fool our system, but by giving a unique `id` (which is numeric) to each user you can also prevent this. – Pawan Choudhary Sep 05 '11 at 14:23