This post is a long and exciting story of the way we have created anti-hacking and anti-cheaters HTML5 game system, what challenges we have met on this way, how we have overcome them and what results we have after all. You all know the main problem: eventually (very soon, in fact) someone creates a bot that automatically wins the game. In our case, a bot was easier to write, since the game code was publicly accessed, and more likely to worth trying: the game was for real prizes, like iPad, show tickets, USB flash drive, etc.
We hope that the post will be useful for HTML5/Flash games developers, which take care of the security; those who pay for these games development; those whose job is to find and eliminate bots among all.
What’s the game?
A few words on the game itself. Alas, we cannot show it since this is the customer’s demand. Though we used effective methods described hereunder, “not knowing” stays a key element of protection. If we describe these methods on the exact game example, that will make them far less effective.
- Game type: Collect& Run, like well-known Mario Bros. and its clones.
- Game duration: 1 – 2 minutes.
- Game goal: receive maximum points.
- Main game elements
- The Character
Main playable character, that always moves. May jump or bend to collect bonuses and avoid handicaps.
May give extra points or increase the character’s speed. To collect them, a character must jump.
Barriers or objects that move towards a character. To avoid them, a character must jump or bend. If a character meets the handicap, his speed slows down.
- The Character
- Game options used for result calculation:
- Points received. They increase with bonuses’ collection.
- Character’s speed. Decreases with time. Decreases at crash with the handicap. Increases with bonuses’ collection.
- Time played.
- Technologies we used:
- Client: HTML5. Main reason was to launch the game on nearly all possible devices.
JS-framework: Pixi.js (http://www.pixijs.com)
- Server: PHP, Framework: Zend
- Customer’s objective: brand marketing in the game. Game process is tightly connected with the company’s services, in game design we used logos, brand colors, and so on. In a fixed time since the game launch, players with best results have received the valuable prizes.
- Based on this condition, one of the first customer’s demands was to protect the game from fake results. Reputation was extremely valuable for the customer. That’s why they didn’t want to receive a negative press – like the news about the branded online game hacked and winners’ results faked.
What’s the team?
We are the web developers, but this one particular team hasn’t developed games yet. Therefore, at the very beginning, we have generated lots of funny ideas. For instance, we have made a crucial architectural mistake – have decided to generate a level in a client’s browser and have hoped that JS code obfuscation is enough for security.
Point that the game protection from fake results was indispensable. However, our team has decided to make the game work at first, and then to think about the security. That seemed logical: we do something, and then protect that something.
When we started to work on the game security, we have stacked in the main browser games problem that is due to their client – server architecture. Exactly, a player sees all the game code, so you cannot simply trust every player on the website. A chance that any user analyzes and changes the source code has become a great challenge for us.
We have started with a simple solution – JS code obfuscation and data encoding (meaning data that a client sends to the server). However, a customer’s security team was so tough that they managed to get unreal game results just in 15 minutes with totally obfuscated code. Data encoding didn’t look like a good variant – all keys are stored at the client’s side, so they are easy to be inserted at any place. In fact, both these solutions fitted to secure the game from extremely lazy hackers.
Advice from the Web
Though there are many online games developed for today, there is no much information on their security in the open web resources. We have found some advice in the WWW boundless space, here they are.
- Hiding, securing, and encoding game data:
- Variables that affect game results shouldn’t be placed in the global scope. They must be claimed as private and placed in closures.
- Do not send open game results, but mandatory encoded.
- Encode addresses (uri), which used to send game results.
- Obfuscate a part of the code, which is reliable for game results calculation and sending.
- Send license keys with the game results and check them on the server.
- Pro: easy to realize.
- Contra: hacked in 15 minutes, as described above.
- Fooling hackers:
- When faking game results is clear, a hacker still sees his result in the records table. Let him think his job is done. Other users should not see that.
- When the game is considered hacked, the penalty is delayed for a random period (for example, 1-3 days). A hacker will use several methods, and sometimes he will see success. But which methods are successful? He will not know. And he will not understand when he was caught.
- Check if game data are realistic:
- Check on the server if received results are theoretically real. For example, energy cannot be negative, score cannot drop, player’s position is always increasing, etc.
- Send game data to the server and compare with the data from other users. For example, a player makes 200 shots and gets a score of 200000 points, and other players after 200 shots get average score of 5000 points: that’s a reason to question if the game was fair.
- Delete the games that lasted significantly more or less than definite time.
- Pro: relatively easy to realize.
- Contra: these methods don’t guarantee full security, but just add 5-10 more minutes to the hacking process.
- Use accounts management:
- Add value to account, so user would regret to lose it. For instance, to play the game with valuable prizes, a user must get noticeable results in other games, without prizes.
- Charge for account registration.
- Ban hackers’ IP at the first hacking attempt. Don’t let them take any time to figure out the game mechanics.
- Emulate game on the server:
- Create instant replay on the server. After the level completion send the data to reconstruct game events and recount its result. Then compare the result with the one received from a player. If the difference is noticeable, that is a hack.
- Pro: high security level.
- Contra: game events sent by a client might be also faked.
We have taken a brainstorm and have generated some more ideas. They were either good or not. Among the last were using captcha before, during and after the game. Or getting screenshots of the game process and sending them to the server for a check.
After all, we have realized several of the most interesting solutions, described further.
After long time of resistance to the most complicated solution, we have decided that game emulation on the server is necessary and imminent.
That’s why we have started to generate the map (bonuses and handicaps positions) on the server and send not the final game result from a client but game events only: meeting handicaps, collecting bonuses, pressed buttons. Each event has a time, coordinates, and data on buttons pressed or bonuses/handicaps met.
There was an idea to send only data on pressed buttons, and then calculate the game result on the server. But this idea has crashed because of the game speed difference on variable devices and in different browsers. The serious deviation in the game process for a client and the server was possible, and this method was very sensitive to any mismatch. For example, if a client doesn’t send just one event with handicap met, the emulated game will continue quite different way than the original one. A character loses his speed and energy, but the server will not “know” it.
Another available option was to process all events on the server and instantly send the results to a client. This method is used by many MMO games. But it generates a lot of traffic between server and client, increases game response time and the server load. For a small Collect & Run game, it wouldn’t be a reasonable and appropriate way.
One fact should be pointed: the game was launched on variable devices with significant performance difference. On ones with high performance, it ran smooth, on ones with lower – with pauses and spurts. Because of that, we had to abandon taking time for account at emulation. Instead of it, we considered game events as objects with definite coordinates. The example: at first, the jump for a bonus was described as “button pressed at 10 seconds, bonus met at 12 seconds”. However, what fitted the game more, was “button up pressed at player’s coordinate X = 1000, bonus met at player’s coordinate X = 1000 and Y = 300”. That helped emulate the game the same effectively for faster and lower speed on different devices.
As a result, we have decided to emulate every game event on the server after it is received from a client, and, in addition, to count the events’ probability. One of the tasks we had to complete was a production of the identical impacts counting algorithms on the server and on a client. We need to get the same preciseness, including rounding.
After the emulator processes the game we receive the game events sequence on the server in the same form, compared to the real game. After that, we are starting to analyze the result.
That’s probably the most interesting part. We have collected and used the most interesting methods to find cheaters. They all are different, and more methods might be added on demand.
Crash with the handicap or collecting the bonus has happened on a clients’ browser at the same point as generated on the server.
- Character’s position increasing
Character’s position in a game should increase over time. It cannot decrease or stay unchanged.
- A character reaches the level’s end
Maximal character’s position does not exceed the level’s length generated on the server.
- Game time
Level cannot be completed in time less than 1 minute and doesn’t last more than 2 minutes. So the games completed in 30 seconds or more than 2 minutes are considered hacked.
- Speed and energy indicator control
The indicators’ value in clients’ browser must relate game events (collecting bonuses, handicaps crashes). Collecting some bonuses increases character’s speed, meeting handicaps decreases it. Collecting other bonuses gives a player extra points. If we know what events a player had in the game, on the server we may count values for all his indicators: energy, speed, score.
- Jump for a bonus collection
Bonuses are placed high, so a character must jump to collect them. We check if he pressed the related button.
- Jump for a handicap
To avoid a crash with a handicap on the ground, a player must also jump. For each handicap, we check if he has jumped before it (jump button was pressed) and if the jump trajectory was enough to avoid the crash.
- Right buttons
We check if the definite buttons were pressed: “up” and “down”. If a player has pressed other buttons, that might be suspicious activity.
- Bonuses and handicaps are met once
A user may collect each bonus and meet each handicap just once along the game.
- Crashes on a client
Compare the crashes happened on a clients’ browser with ones calculated by the emulator on the server.
- Crashes on the emulator
Compare the crashes calculated by the emulator but not happened in the game. This method was added to get different weights of this and a previous comparison. We considered that if there’s a crash on the emulator but not in the game – it is the same suspicious as in the case when there’s a crash in the game, but not in the emulator.
- False elements
At the game generation, we have added several bonuses that are impossible to collect at a fair game. For example, they are placed higher than a character may jump, or there are two bonuses so close to each other that a character may physically collect just one of them. We check if a hacker took a bait and collected these false bonuses.
- “Fingerprints” analysis
Before the game starts, at registration and login we collect clients’ information (browser plug-ins, HTTP headers, IP, installed fonts, screen size, and colors). That doesn’t help us understand if the game was hacked. But when administrators mark a player as a hacker, analyzer scans all players in the system and finds the same “fingerprints”. It helps with the certain probability reveal those criminals who may hack the game under one account and play fair under another.
Each method has its customized weight in the calculation. By the way, it is reasonable to take into account as many parameters as possible, since you never know in advance how sensitive or rough each algorithm is going to be in a real game.
Analyzer gives each method a value from 0 to 1 (0 – game is not suspicious, 1 – test failed) and calculates the final “Game suspiciousness index”, also from 0 to 1. This index is used for automatic games marking. If it is above the threshold, the game considered hacked. The threshold is defined experimentally, in our case it was 0.4.
Then you need to do something with all these calculations. One task is to develop all algorithms described above, but to give the results of their work to the game administrators is a completely different thing. A player blocked for hacking may claim to the support, and they should have a proof for the account block. That’s why administrator should have all possible information at hand, to make a decision and to argue the hacked game status.
That’s why we created the back-office with the four following elements.
Game info – Emulator
Table with the real and the emulated game events. Has these columns:
- element type (bonus, handicap),
- X and Y element’s coordinates,
- time on a client,
- X and Y character’s coordinates on a client,
- meeting of a character and an element (yes or no),
- X and Y character’s coordinates emulated on the server,
- the probability of the crash at a time on a client.
- Game info – Analyzer
Total game suspiciousness index and a table with results for each analysis method.
Show a complete table of all suspicious games using a threshold (0 – game is definitely clear, 1 – game is definitely hacked). Experiments resulted in 0.4 threshold.
- Players’ page
We have added “Player’s hacker index” to the profile. It is calculated from all his games suspiciousness indexes.
How it all worked
It was extremely exciting and curious, to analyze players’ top in several days after the game launch. One hacker took the easiest path and has collected all bonuses, but hasn’t jumped at all. He has also collected all false elements. Another “champion” had a kind of consistent evolution. At first, he played a dozen of fair games, then lots of ones with middle suspiciousness index, and for the several latest games, the index was close to maximal. Some “winners” have completed the game less than in 10 seconds. Someone played just once and managed to get to the top. This also might be used as the analyzer parameter – there are few players who can get maximum points in the very first game. There were “records men” which got unreal points score in 1 second. And so on. They all were blocked and didn’t receive any prizes. They did not claim.
After dozens of real games reviewed, we have updated some threshold parameters – mostly have increased them. The starter parameters were too much “suspicious”.
As a result, we have received a positive experience of this system in action. Results display in back-office helped a lot. After all, we may say that the system was vital and worked flawless enough to guarantee the customer’s satisfaction.
We used the data from the only one game to secure it from fake results and were trying to find its’ all possible inner mismatches. We presumed that the game was completely vulnerable: all its’ source code was available to the player; all the incoming data were unreliable. So there was only one game part that could not be hacked – all games’ data. We had an assumption that correct usage of the database from thousands of players may help increase hacking detection accuracy. Now we suppose that the game results database is the main developers’ advantage over the hackers.