This forum is read only and just serves as an archive. If you
have any questions, please post them on github.com/phoboslab/impact
Has anyone given any thought of how to keep your game reasonably hard to hack when you're dealing with a client->server game (for example, a facebook game or mmo)?
The openness of JS being easily parsed (even when obfuscated) and edited in the browser will open up quite a few easy avenues to cheat and hack games. Some of these can be done in Flash - but many more are very hard due to it's compiled nature.
I was wondering your thoughts - as I'm going to have to deal with this and the options seem minimal.
I've also been thinking about this lately. It's also occurred to me that de-baking a game isn't hard at all, making it very easy for others to get the majority of the Impact library without having to pay.
If your game has a highscores function, one way would be to set a maximum score. Chances are if there's only 500 points available in the game, then getting a score of 1000 isn't possible. And therefor a cheat. Even so, for someone to download all the games files, edit the highscore function a little and surpass it wouldn't be too hard either.
There's not much anyone can do about cheaters. Embrace it by including cheat codes or easter-eggs. Activation a cheat disables the scores or something. Modern console games do this all the time. GTA is a great example of a game packed with cheat codes, that millions of people use. But doing so has an adverse affect on the game. In the end people will play how they want to play, all you can do is try and distract them from cheating and hacking it.
Then again, if you want some "security" one idea would be to have the game not load or be disabled in some way if it's not accessed via a specific url. Something that simply checks that its running on your server instead of a local machine or looks at the URL in the address bar. Think about how software checks that it's registered. Serial codes and checks with a server.
Hope that helps a little, I realise it's not really linked to Facebook hacking etc, that's totally beyond me, so I have no idea about that bit. :P
1 decade ago
Yeah, I too have been thinking about this a lot as of late and have come to similar conclusions. There is not much we can do that would hide the code from anyone who wants to view it and possibly alter it.
I agree with Hareesun about having server code to do sanity checks on the incoming data to make sure they are at least possible. One could also create a weighted scale, so that anything that comes in with X points for this board is fine, anything is Xx points is very hard to do and unlikely, Xxx is probably a cheat and XY is surely a cheat.
One way I was thinking about making it more difficult for someone to cheat is if the game writes back to a server to record the metric in a DB, is to either have page query the server every X time period via ajax, to get an "auth token" that will only be good for X minutes. So if a GET or POST request comes in via ajax to save the score or game play it checks if the token is what it is expecting. If it is, it writes it, if not then it flags it as a cheat.
This would also be coupled with a login system either via your own login, open id,. Facebook, etc... would cut out a good number of the people who want to cheat. Unless of course you are Zynga. :)
But the best solution that does not work for all games is to have the logic run on the server and the JS/HTML is primarily for display.
I'm not sure yet how affective this will be. It possibly will make it more difficult for someone to send in a cheat request
1 decade ago
One technique that can be quite effective for certain types of game is the idea of an 'instant replay' system. Once the player has completed a measurable round of play, sufficient data is sent to the server that it can then reconstruct the events of the game, and see if the final score (or whatever you're measuring) matches what the client provides. Again, this certainly wouldn't work for all games, but if yours is a good match for this method, I imagine it would work pretty well.
Yes - to be clear I was less talking about viewing the source and more about assuring that people don't hack the game to do unreasonable things.
It pretty much puts all responsibility for the game on the server side - the visual code and basic logic would be done in something like Impact but everything has to be validated and/or effectively re-run on the server.
For a company or team that is used to Flash games this is a big cognitive leap to make - and a hard one to convince people about. Flash can be hacked (memory hacks) but a lot more logic (hashing algorithms for secure validation for example) can be placed in the front end code.
Take, for example, CityVille - or any Facebook game for that matter - the user actions submit requests that are validated on the backend. These requests are passed with a generated hash - to make sure that the request is actually from the Flash file. The hash is generated in the flash based on the data it is sending.
I can't see a way of doing this securely with a html5 game. Without something like this you can't really do any kind of serious game - especially not one that uses real money.
1 decade ago
@abritinthebay - I'm not primarily a game maker nor am I familiar with flash programming. I do however have experience with using Rails and ajax. For my Rails projects I have used a combination of authlogic
plugins to handle user authentication and web page permissions respectively.
For my pages which use ajax, the Rails app will create a unique hash (called a token in this case) which can be assigned to the page. When the ajax call is made (in my case via jquery), the hash must accompany the data which is sent to the server. The server then authenticates by looking for the unique hash for that user and that page.
Although I haven't tried this with Impact, I don't see why it wouldn't work. I would suspect other frameworks in other languages - python, php, etc. - have similar ways of doing ajax call authentications.
@MikeL the problem with that is that you are sending the key to the (hackable) front end. Any hashing calculation is therefore on the front-end and therefore hackable.
The links fugufish posted go into it in more detail, but basically they confirm my original thoughts: there is no way to make a secure game in HTML5 right now. None. Zip. Nada.
All calculation must be completed on the server to be secure. All HTML5 can be trusted to do is the rendering pipeline - it may run game logic, but that logic must be repeated and then periodically checked on the server.
In other words - game development in the browser with HTML5 where there are actual monetary consequences to hacking - is exponentially more complicated.
This might be why there isn't widespread development of this is major online game companies right now - it's not very practical for most of the game models they use.
A game like Farmville (for example) will never be developed with the current technology - it's just more work for less benefit.
That's kind of sad :(
1 decade ago
@abritinthebay: Just thinking outloud (in hypertext?) here, although it would somewhat defeat the point of using HTML5, what about creating a hybrid Flash/HTML5 game? Flash would just sit invisibly in the background, but could handle the security issues you were talking about. Therefore communication would run:
Impact <--> Flash <---> Server
Not sure if you would just be duplicating the problem in a different way though with the the Impact to Flash part of the communication....
#MikeL - I've used flash for sound before in that exact fashion (and it's a really nice way of doing it on flash supported devices).
The way it would probably be implemented is that the game sends its data to the flash, the flash encodes/hashes it, and then sends it to the server. However that really just moves the problem from being html5 --> server to being html5 --> flash. You still can't trust the data from html5 as it's client side code.
Also it removes the portability of the code to iOS/mobile, which is a big deal.
a Farmville-like simulation game, where ONLY the player's actions (buy X seeds, plant, harvest) are sent to the server.
data gets processed ( using feasibility tests ) to root out cheaters, and sends results back to client. The tests could be simple ones like: can the user afford building the barn? Does she have enough energy and coins?
virtual goods system can be implemented from other sources (eg: Tapjoy http://tapjoy.com
, Zong http://zong.com
, Super Rewards etc).
Buying 1000 Haiti Seeds means making a request to Tapjoy's servers, and your server gets the return code, which you pass on to the client (ImpactJS). We basically shift all security responsiblity to the virtual currency experts.
Essentially, this idea can be used for 'slow paced' simulation games, where the game logic stays in the servers. Don't think it can work for a 2D shoot em up game (because there's too many actions to send to the server per second, plus the game logic tends to stay in the client, which is bad for security).
now consider this:
for 2D platformer shoot em ups (like Biolab Disaster), we can take the main actions (no. of shots, kills, deaths, time spent, player movement points per second ) and send them to the server after the player completes each level. We try to construct a replay out of it, sandwiching feasibility tests in between. If a logical replay is constructed, the data is assumed valid.
btw this technique works perfect for puzzle games like Angry Birds, or Cut the Rope, because replays can be constructed fairly easily.
It's that "feasibility" step that's the killer though.
You're basically duplicating game logic - once in the client, once in the server. You have to do that to check the users actions.
As I said above - more work for less benefit.
Not to mention that this doesn't actually fix the problem. Yes it'll catch the impossible cheaters who are doing outlandish things... but it won't fix gaming the existing rules in record time. It would be trivial to automate things so you have a perfect game.
That's not good.
Like I said - there is no way to make a game whose communication is secure in html5 right now. And - as has been confirmed by the suggestions here to work around that - game development where there are actual monetary consequences to hacking is exponentially more complicated than with Flash as you'd have to duplicate everything in your game logic...
.. I really want there to be a solution to this, but it looks like limited turn-based games - ones with no significant real-time calculations - are as good as we'll be able to get right now for practical commercial development.
That's not a bad thing as such, but it does mean that we should acknowledge this problem and try to work out a way of fixing it...
1 decade ago
1 decade ago
@wavyGravy - I'm not sure I'm follow the suggestion, but I don't think this will work because the JS code is executed client side and I can alter any JS file and have it execute, so your server will still see it as legit. This includes any data that might be used by the MD5 hashing you mentioned. The only way to secure the code is to have the HTML/JS as just a render engine and all game logic executed on the server.
I could be totally mis understanding your post, or be missing something so please let me know if I am because I would love to find a way that does not involve the server side game code :) but I don't think there is one.
- make it so that using any consoles (such as Firebug, Chrome Debugger, etc) will be idenfied by your server code as a 'hack attempt', and therefore is not valid
- perhaps designing the game in a way that it doesn't incentivize high scores...
- or let the user post all they want to your server, but make the server smart enough to know that posting too much, or too often, or too many points (like, a zillion) is viewed as a hack attempt.
I read somewhere that OpenFeint uses the same technique for mobile app scoreboards. They hide the key somewhere within the app, whose code is up to now isn't really readable unless you can reverse engineer it.
don't let security issues hamper your attempt to make an awesome game!
1 decade ago
You made some good points fugufish. You're absolutely correct when you say "don't let security issues hamper your attempt to make an awesome game!".
You are also correct about Flash being similar. At my previous 9-5 at a marketing company I was creating the "backend" of Flash games / contest for our clients and basically all game logic was on the server and Flash just rendered what the server told it to. Obviously this gets a little harder depending on the type of game.
To the point of obfuscating the code, if you are really worried about hiding and protecting the code just be sure that you encrypt, obfuscate and randomize what is being sent to the server via ajax GET/POST, because even if your JS code is obfuscated and I can still see / guess / hack and spoof what is being sent back to the server.
That all being said, when dealing with JS you are giving the client the source code, obfuscated or not, so it won't ever be "secure". It will only be a pain in the butt to try and figure out. That is why you are correct about making the server "smart" if you are really concerned.
My way of thinking is with JS games 99.999% of the people who will play your game, just want to have a bit of fun. The goal should not be to worry about securing it like it's a bank, most people who play your game are not going to care or try to hack it anyhow. Of all the online contests I've built at my previous 9-5 where people entered to win free prizes / product, we had very low percentage of people who tried to cheat. Yes we did see some attempts, but when you have hundreds of thousands signing up you will see that. Just make it hard enough that it's not worth their time to hack it and be #1 on the leader board or get an extra 10 pieces of gold.
To bring it back to your comment of "don't let security issues hamper your attempt to make an awesome game!". You are very right, don't spend all the time worrying about and building out an elaborate security scheme, just built an awesome game that if fun to play. There's a slim chance we will be the next zynga. You can always worry about encrypting, encoding, obfuscating after you see anyone cares about your game.
@ken You're totally right about not worrying too much about security and you should worry about making a great game. My suggestion isn't secure proof but it'll make it a tad bit harder for them to hack by encrypting the data that is sent back to server. I figured that encrypting the data by using an MD5 hash will just make it slightly tougher. JS is capable of doing that. A solid way of encrypting would be awesome for web browser based games.
What about checking important values (score, lives, ...) on the server side, let's say something like every 1-2 seconds, and if the new value is to high or impossible, revert to the previous value or abort the game/cancel the highscore ?
Would be this technique secure enough ?
I was just testing to edit the score via firebug and it's really to easy to do...
Maybe it's the only solution.
i'd stick to ken's advice. @ygosteli - yup server side checking is a good strategy.
One strategy would be to use the server to keep track of score / time played etc.
- Send score updates to server via AJAX every ten seconds or so. Server checks time elapsed since last score update and nullifys crap.
- Same for lives lost - if user suddenly has more lives then do some stuff...
This stragtegy is used a lot in Java games that can also be un-compiled.
EDIT: Opps - didn't see ygosteli comment.
1 decade ago
I've had remarkable luck using Google Closure. I couldn't quite get Uglify to uglify everything as much as I'd like, but I did like its compression capabilities. Maybe the best approach it to use Uglify for compression, then closure for obfuscation?
You don't have to modify your source at all. All you need to do is add the core impact js files as externs to the compiler, and use the ADVANCED_OPTIMIZATIONS flag.
Here's a sample:
java -jar compiler.jar --jscomp_off=internetExplorerChecks --compilation_level ADVANCED_OPTIMIZATIONS --warning_level=QUIET ./lib/game/ai/ai.js ./lib/game/ai/aiSimple.js ./lib/game/board.js ./lib/game/constants.js ./lib/game/main.js ./lib/game/structures.js --externs ./lib/impact/animation.js --externs ./lib/impact/background-map.js --externs ./lib/impact/collision-map.js --externs ./lib/impact/entity.js --externs ./lib/impact/animation.js --externs ./lib/impact/font.js --externs ./lib/impact/game.js --externs ./lib/impact/image.js --externs ./lib/impact/input.js --externs ./lib/impact/loader.js --externs ./lib/impact/map.js --externs ./lib/impact/sound.js --externs ./lib/impact/system.js --externs ./lib/impact/timer.js
Thanks for the tip MDicksonJr. ;)
1 decade ago
@MDicksonJr - so you didn't need to use the bake script at all, just put it through Google Closure?
You might have to bake the impact engine at least. The example he gives only references Impact and doesn't compile it. The engine itself will have to be included separately. At least that's my understanding.
Page 1 of 1