HTML5 Consumable items in HTML5 and how to prevent cheating?

G

Guest User

Guest
I was trying to figure out how to secure items amounts in HTML5, such as "gold" amount, and "money" amount. Since the player can change the codes whether using a cheat engine or directly changing it using the inspect element; assuming we use ini.

So here is what I'd thought, I am gonna make the steps as a list so it'd be easy to follow
  1. Store the players' data in a server
  2. Retrieve the player's data when he starts
  3. Everytime he consumes/uses the items I send a request to the server to reduce the amount
  4. Everytime he gets an item I also send a request to the server to increase the amount
That is the only approach I've took, so far; but I've got some concerns about the performance and security
  • Sending and receiving requests will definitely slow down the game
  • Users can use some client-side tools or debugger to edit AJAX calls and send hacked data to the server

In Stackoverflow someone said
Do not worry about it; protecting from all attacks is essentially impossible if you trust the client. If nobody uses Fiddler etc, to modify the AJAX request, they can simply fire up a JS debugger and modify your game data to give themselves 1000 lives, etc, or modify your code, or do 100 other things you haven't thought of.
I've played some games online "Farmville" and some others, they really had secured data, for example I never was able to edit the data using "Cheat Engine" or hack it with other softwares, maybe because it was hosted on Facebook? I don't know.


What do you think? is it possible to secure HTML5 games?

Thanks in advance!
 
Last edited by a moderator:
Performance wise, if you are relying on getting information from your server and updating the GUI during the game and making it visual to the player, then yes, this is costly. If you were only getting the information, simply do it at game start, but from what I understand, you want to update the server and client side and it needs to be visual.

You could probably have an authoritative server with reconciliation and client side prediction, this way, there won't be a delay, but rather a rollback if some sort of rejection came from the server.
 
G

Guest User

Guest
Performance wise, if you are relying on getting information from your server and updating the GUI during the game and making it visual to the player, then yes, this is costly. If you were only getting the information, simply do it at game start, but from what I understand, you want to update the server and client side and it needs to be visual.
I thought about it, I will load the user information/data at the game start, and then I will send an AJAX call every 30 seconds that updates the database, given the fact that I only send, no receiving afterwards.
I've also game across the "beforeunload" event in Javascript that might help me. When the player closes the game tab or the browser, this event will fire up and send a quick AJAX request. I hope it will be fast enough to make it.

You could probably have an authoritative server with reconciliation and client side prediction, this way, there won't be a delay, but rather a rollback if some sort of rejection came from the server.
I really don't understand what you mean by this line.

[EDIT]
I can clearly see an improvement in the system, I did some server-side coding and managed to protect the data. I am really pleased with the results!
 
Last edited by a moderator:

Tsa05

Member
Generally, the client simply passes inputs to the server; the server computes the result and returns the new value.
In this way, the client can trust that the changes have been received and counted by the server, and the server can trust itself to modify values.

In practice, this rarely happens. Games do so much "stuff" at once that transacting every little thing is just too much. Instead, setup is basically:
1) Client: Hey server, I'm gonna do a thing
2) Server: Ok, here's <data> that you need in order to do the thing
3) Client: I did the thing! Here's my results!
4) Server: Hmm, action A is within tolerance A, action B is within tolerance B...yea, ok. Here's confirmation that the thing was done!

So, the client puts together a list of actions that are being done, then locally computes results, and sends off a set to the server, which ensures that the player hasn't "moved beyond their speed" or "used an ability that's on cooldown" and so on. In sophisticated cases, random numbers are checked, too; the client receives a "random seed" from the server for a set of actions and checks that random decisions followed the correct probability.

Mobile App "raid" (the kind where players contribute to a common goal within a multi-day raid window):
1) Client: I'm entering raid!
2) Server: Here's the current state of the raid and the random seed to use
3) Client: Here's a list of actions I took during my turn in the raid!
4) Server: Here's the new state of the raid (based upon verifying that the actions list you submitted is valid and the numbers generated as a result)

FPS:
1) Client: I pressed BANG while pointing at angle A, at <this> moment in time
2) Server: Based on time differential, that guy was within <tolerance based on movement and time> of x,y coordinates described by your position and angle A, so you hit the guy
3) Client draws guy falling down.

Netcode is hard, though--time makes everything a mess. So a lot of clever massaging is needed for real-time data syncing; this is why turn-based games let the client basically do its own thing most of the time, and then the server just checks a series of rules regarding "how often" and "how much" for a set of submitted steps.
 
G

Guest User

Guest
Generally, the client simply passes inputs to the server; the server computes the result and returns the new value.
In this way, the client can trust that the changes have been received and counted by the server, and the server can trust itself to modify values.
That was my number 1 concern, the player can use a debugger or tool to edit the AJAX requests sent via GM and change everything, I really have no idea of how to protect the data beside hashing every key along with its value everytime I run the game.

I guess there is a function in GameMaker that checks how many seconds that game had ran, I could use it to check how much the score had increased within a determined time, for example a player had scored 1,000,000 in 5 seconds, which is obviously a scam so we don't record his/her score.

When it comes to security my knowledge is very limited, I hope some server-side scripting can prevent hacking.
 

Tsa05

Member
I guess there is a function in GameMaker that checks how many seconds that game had ran, I could use it to check how much the score had increased within a determined time, for example a player had scored 1,000,000 in 5 seconds, which is obviously a scam so we don't record his/her score.
Yep, the server can check time.

Let's imagine a basic "click the dot for points" game:
Client: I'm ready to play!
Server: Use random seed <number>
Game spawns dots on a random interval for 60 seconds and awards points per dot clicked
Client: OK! I got a score of <score>
Server: <check max score * number of dots that can be spawned in 60 seconds based upon random seed> <optionally checks something like how much time elapsed since the random seed was sent> Replies with confirmation of score if it's within reason, or error if it's not.

Otherwise, you could write a *very* custom server like this:
Client: I'm ready to play!
Server: Use random seed <number>
Game spawns dots on a random interval for 60 seconds and awards points per dot clicked, displaying an unofficial score
Client: Ok, here's a series of mouse-click coordinates and time-intervals from the start of a game round.
Server: <simulates game, instantly computing positions of random dots as they would appear at points in time according to the times sent by the client. The positions submitted by the client must be within the radius computed for each circle based upon the server's random seed> Server returns final score.
 
G

Guest User

Guest
Server: Use random seed <number>
I don't understand the use of "random seed"?

Say we have a building game, and the game has "wood", "gold", "stone", and "food" therefore the game scenario would be like this
  1. Player starts the game and logs in with either their Facebook or game account
  2. Server sends the user data, say "wood = 125", "gold = 325", "stone = 200", and "food = 750"
  3. The player starts playing, building stuff, say he consumed some items and the final result is "wood = 25", "gold = 125", "stone = 50", and "food = 250"
  4. Again, every 30 seconds an AJAX request is sent via GameMaker with http_post_string() function and it updates the database row with the current data as a json {"wood":25, "gold":125, "stone":50, "food":250}
  5. When the play exit the browser a beforeunload event is triggered sending the same as the above ajax request.
This is the exact scenario of the game! but now we're left with hacking, say
  1. Player starts the game and logs in with either their Facebook or game account
  2. Server sends the user data, say "wood = 125", "gold = 325", "stone = 200", and "food = 750"
  3. The player then opens a debugger, editing the AJAX request to send {"wood":999, "gold":999, "stone":999, "food":999}
  4. The server has no idea the data is genuine or hacked so it updates the database row with it
From what I understood from the above steps I can clearly see all the security happens in the server-side code, it kinda need some advanced AI that tells which data is genuine, and which data is wrong.

Thoughts?
 

FrostyCat

Member
It's scary to see someone who offers a payment processor service asking questions and designing servers like this.

In a secure setup, at NO POINT should the client be allowed to lord over the server on anything that has direct leverage on global state. Steps 4 and 5 in your current design clearly fall under the "direct leverage" category. The only commands that the client should be able to send are commands for creating new buildings, and even then, the server should have the final say on whether that goes through and how much is left afterwards. If you don't want to wait for the response, you can simply deduct the local resource counts and move on. That's a client-side matter, it is free to do whatever it wants. To remain in sync, the client can poll the server for resource counts every once in a while, and if the counts are off beyond some threshold, the game should pause and update according to the server's state.

And this hope about being able to slip in a request upon closing the browser is just plain naive. Common sense should have told you that the on-unload event cannot outrun Ctrl+Alt+Delete, the power button, or any other system- or hardware-level kill. Getting the Game End event to run should always be treated as a limited privilege, never an undenied right. On HTML5, iOS and Android, that privilege is out the window altogether. This is the other reason why having the server process the authoritative state is important --- the client is much more fragile and prone to being interrupted.
 
G

Guest User

Guest
In a secure setup, at NO POINT should the client be allowed to lord over the server on anything that has direct leverage on global state. Steps 4 and 5 in your current design clearly fall under the "direct leverage" category.
These functions should be triggered everytime a player builds something?

The only commands that the client should be able to send are commands for creating new buildings, and even then, the server should have the final say on whether that goes through and how much is left afterwards. If you don't want to wait for the response, you can simply deduct the local resource counts and move on. That's a client-side matter, it is free to do whatever it wants.
So when the player builds something a request is sent to the server to update the remaining resources, it doesn't return anything but keeps using the local game resource.

To remain in sync, the client can poll the server for resource counts every once in a while, and if the counts are beyond some threshold, the game should pause and update according to the server's state.
Every once in a while, a request is sent to the server requesting the current resources, if the data are beyond some threshold (kinda of range?) the resources are updated with the responded one, otherwise keep it. Truth be told, this is a great idea!

And this hope about being able to slip in a request upon closing the browser is just plain naive. Common sense should have told you that the on-unload event cannot outrun Ctrl+Alt+Delete, the power button, or any other system- or hardware-level kill. Getting the Game End event to run should always be treated as a limited privilege, never an undenied right. On HTML5, iOS and Android, that privilege is out the window altogether. This is the other reason why having the server process the authoritative state is important --- the client is much more fragile and prone to being interrupted.
I just learned that event today, thought it would keep track of resources even after exiting the game; Yes, common sense did told me that, but thought it is better than nothing, afterwards saving the resources after the user exits is what I wanted.

Thanks so much for the ideas, they're pretty useful!
 

Tsa05

Member
I don't understand the use of "random seed"?
Ah, so for example:

A game in which events occur randomly, or damage or effects occur within a random range, etc.
In the game shown above, the entire 5v5 battle occurs client-side, but the server is able to know if the client is lying about the results.

In GameMaker, try this:
Code:
random_set_seed(1);
repeat(5){
     show_debug_message(irandom(10));
}
show_debug_message("-------------------");
random_set_seed(1);
repeat(5){
     show_debug_message(irandom(10));
}
You should see 10 random numbers generated with a separator in the middle.
The top 5 numbers should be exactly the same as the bottom 5 numbers.

Inside of a computer, there's no random. Only formulas which produce sequences of numbers that look random. The random seed is a number that is used to generate the sequence of random numbers. Each time I request a new random number, the computer actually just gives computes the "next" number in a sequence; As such, every single time I request a random integer from 0 to 10, I'm really just getting the "next" number in a sequence of numbers according to a formula.

If I change the random seed to 2, it's like telling the computer "don't use the 'first' sequence of random-looking digits, use the 'second' sequence." The seed can be whatever you want.

The point is, you can allow a game to to totally random things, but you can verify that the randomness worked.

So to go back to your example, you wouldn't say final result is "wood = 25", "gold = 125", "stone = 50", and "food = 250"

Player loads game, server tells player how much "stuff" they have. Then, the server might say things like this:
Code:
{
   "trees": [
                     {x, y, idNumber, minWood, maxWood},
                     {x, y, idNumber, minWood, maxWood},
                     {x, y, idNumber, minWood, maxWood},
                  ],
   "mines": [
                     {x, y, idNumber, minGold, maxGold},
                     {x, y, idNumber, minGold, maxGold},
                     {x, y, idNumber, minGold, maxGold},
                   ]
}
Player replies with something like this:
Code:
[
   {
      "actionType": "chop",
      "entity": idNumber,
      "amount": xxx
   },
   {
      "actionType": "chop",
      "entity": idNumber,
      "amount": xxx
   },
   {
      "actionType": "mine",
      "entity": idNumber,
      "amount": xxx
   }
]
Using JSON here because it's easy to see the structure (and it's a common API format, and GameMaker supports it)

To explain, the server tells the player "any data needed."
In the case of the GIF I linked, the data needed is the opposing player team members and their gear level and unlocked abilities.
In the case you described, it could be something like "here's the trees and gold mines available right now"

It could be all sorts of things, depending on what you want to check. I'm assuming an example where the server says "here's the trees and mines available and the range of how much gold or wood they yield"

So, a player responds with an ordered list of actions:
"I chopped tree number such-and-such and got xxx amount of wood"
"I chopped tree number such-and-such and got xxx amount of wood"
"I mined mine number such-and-such and got xxx amount of gold"

In this way, the server can now rapidly iterate through the response list and can see what the player did. The server can now apply corrections if needed ("oh, player 2 chopped that tree just before you").

Now, the server has an accurate picture of the player's stats. The player can, of course, hack the client--they can make it say "I have a zillion gold." But the server doesn't care about what the player has. It computes the gold on its own when the player says "I mined mine # such-and-such". If the mines yield random amounts of gold, that's where the seed value comes in. The player can tell the server "oh, yea, I mined and got a ton of gold" but the server simply says "ahhh, next you mined that mine, so random number from a to b with that seed is...X gold, so that is what you gained."

Player tells the server "I did a thing" and server records how much gain or loss that would be. If the client and server drift out of sync, the player is cheating. But the server doesn't care--its own records are accurate.

Of course, with this model, the player sends a trillion "I chopped a tree" messages, and virtually clears the forrest in one command.
But, your server might perform a secondary check: where is the player?

Servers have to do this a lot. Players love to cheat with movement hacks, so there's a lot of verifying inputs and speed and averaging that stuff. If the player says that they held UP Arrow for 293048594352374 seconds and chopped every tree in the game, then they are cheating.
 
Last edited:

Yal

🍋 *lemon noises*
GMC Elder
So to TLDR what @Tsa05 said: the client (player's local app) does most computation and sends messages about what they did to the server. The server checks that the messages it gets seems legit, and only actually process the messages if they are. The client itself doesn't change anything in the server database, it tells the server to do it (using the messages) and the server tells it the new values every minute (or whatever time is appropriate). If the player sends too many messages in a too short time, or send messages that they're doing something they currently can't do, they're probably cheating, even if all messages seem legit.
 

The-any-Key

Member
You can always make it harder for the players to cheat. This prevents most players to do it. But in the end you won't be able to create a 100% safe system, maybe not even a 60% safe system. If a player want to cheat and has the skill, he will be able to cheat whatever security you put into the system. If one player can beat the system, there is not much to do about it. But if he dare post the cheat on the web for others to use. Use it yourself, and check what he do to beat your system. Then you can add counter-measurements to prevent it from working. But in the end the only hack and cheat safe system is a disconnected computer sunked in 10 meter thick concrete surrounding it, buried in the ground.
 
Last edited:
Top