So I'm writing a game client using WebSockets. However, I want to prevent people from cheating and sending certain data to the server. Can people modify the html and javascript on the page to change what data is sent to the WebSockets?
If so, how can I prevent this from happening?
This is the big thing about "cheating" and "hacking" in (multiplayer)games. Data that comes from the client (and sometimes even the server) can never be trusted.
Think about a "teleport hack" in a shooter game. Your client is sending your players new position to the server, as soon as you move. If you want to cheat, you can simply manipulate your client to send the coordinates of the position you want to teleport to.
Now there are two possible outcomes:
1) The developers did not care about cheaters, when coding the server side application. The server accepts the new position, although it is impossible that your client moved to that position since the last position update.
2) The developers were smart and wrote an intelligent server. Before accepting the new coordinates, the server validates if it is possible that your player moved to the given location since the last update. If it is, the server accepts it. If it is not, you get banned for the next 1000 years.
Related
Desire: I want to make an ever expanding single player online rpg world. Even though it is single player, I would like to make it possible for people to trade items they find in an online market and rank players. To reduce requests to the server I wanted the local machine to hold all the information in javascript objects until the player presses SAVE. When SAVE is pressed an AJAX request is sent to the server and I'll handle that with PHP, MySQL ect.
Perceived Problem: If I do this my concern is that someone will access the variables by typing javascript:object.hit_points=10000000000000;. If one person cheats and floods the online market with items they cheated to get, then that will cheapen the experience for everyone else.
Questions:
Is it possible for a player to manipulate live javascript object variables through the address bar or some other means?
If so, is there some way that I can secure the game and still use javascript for managing the interface and data?
Thank you for your time in sharing your learning and understanding.
Best Regards,
Bryan
Is it possible for a player to manipulate live javascript object variables through the address bar or some other means?
Yes:
If the variables happen to be globally accessible, the user only has to open the console and assign to them. Eg, they could type in window.money = 999999999;. This could be solved by putting the whole script into an IIFE without using global variables. But...
Even without global variables, no code that runs client-side is "secure". See Is it possible to gain access to the closure of a function?. The user could simply intercept the JavaScript that your site runs, and replace it with their own JavaScript that implements their desired functionality (giving them free items, money, etc). This can be mitigated to a moderate extent by minifying and obfuscating the JS, but it's not a full solution. You'd want to make sure the network request payloads cannot be easily deciphered either.
Ultimately, the only good solution to this is to generate and save all state on the server, which gets communicated to the client when needed. The client cannot be allowed to generate any data or state themselves - the client should only be able to ask the server what their state is.
If the user is at a section where an item may be generated (eg, a treasure chest is opened), the only way to do this securely is for the server to verify that the player is at the position of a treasure chest, and for the server to generate the item in the chest, then inform the client of their new item. This way, no matter what JavaScript code runs on the client, if the client tries to make an invalid trade, or patches things so they have more HP than they're allowed to have, the server can verify it and reject the invalid request. For example:
Client: Attack
Server: You attack and deal X damage. You are counterattacked and lose Y HP. You die.
Client: Open chest
Server: (Verifies that you are at an openable chest, then replies:) You receive a Water of Life
Client: Offer trade of item ID 333 for some other user's item 555
Server: (Verifies that client currently holds item 333, and that the other client holds item 555, then:) Trade successful (switches around items in server's DB)
I have variable in Javascript which are created by reading a number from HTML, adding a number to it and then returning it to HTML.
I want to make it so that no matter what browser/what user you are, you are seeing the latest version of the variable. Currently, if I refresh the page then the number resets to 0 (the default value). I want it so that if I update the number to 1 when someone else views it from another browser they will also see 1 and not 0.
I've seen that cookies are an option, however I thought cookies were client side only? So that would mean that only I would see the latest version of the variable.
I've seen that sessions are another option, are sessions server side? And would they do the job that I am after?
Is there another way of doing this I haven't considered?
Thanks in advance
I want to make it so that no matter what browser/what user you are, you are seeing the latest version of the variable.
You need to send your updates from the browser to a server, and then have that server relay your updates to all the other clients. There are many choices for how to do this, with various tradeoffs and complexity.
One method is to simply take that number and send it to the server. Then, on next page load, the server injects that new number into the page it outputs (or it serves it up via an API call, over AJAX, via the Fetch API, or server-sent events, WebSocket, etc.). If you do this though, you will need to decide how to handle concurrency. What will happen if two people load the page at the same time?
The general system you're describing is called Operational Transform, and this is a rabbit hole you probably don't want to go down right now. Just understand that there's no magic that synchronizes things across the planet perfectly and at the same time. Your system has to account for inherent delays in some way.
I've seen that cookies are an option, however I thought cookies were client side only?
Yes, cookies are client-side. They're sent to the server with every request, but that's not a useful tool for you, aside from session identification.
I've seen that sessions are another option, are sessions server side?
They can be, but you need to find a way to know what the user is between browsers. Normally, a session ID is stored in cookies.
I unfortunately do not have any code examples as I'm not sure what to google as this is new to me and just need guidance on what to google, or packages to use
I want to create a simple application with an Electron GUI that shows me the latency to a server, I'm currently playing a game, H1Z1 to be exact that has no in game latency monitor and I thought it would be handy to have this app open on my other monitor that will show me my connection.
I don't know if I'd need to hook the process somehow and get what ips the process is connecting to and then initiate my own connection and monitor the latency.
I could find the IPs through TraceRoute or something but I don't know if a setInterval with constant pinging of the server is the best option and was looking for the best suggestions on how to accomplish this or guidance on what I need to google. Sorry for the sub quality question.
To clarify as per comment:
Basically the game client will connect to its back end server, and report its response time in milliseconds, which helps you determine just how laggy your connection is. When you're playing a game without this information it's almost impossible to tell if you missed your shot, bullet didn't register, or if you're just lagging and the server takes to long to update the client which can result in desynchronizing from the server and not getting accurate reports from the server, e.g. I shoot at somebody and the server receives its variables and decides well you shot at X,Y,Z but the character was actually standing at X,Y,Z so you missed but on my end I was aiming perfectly, but I can't tell without knowing just how bad my connection is
So I want to create the most efficient method to determine my connection to the server, I'm just not sure how to go about it
I'm basically expecting to see numbers fluctuation could be anywhere between 40-200ms or something. Hope that clarifies.
I'm currently building my first website just for practice. I threw together a quick game of pong in HTML5 and javascript. I was wondering how I could go about turning it into a networked game.
Is there anything stopping me from say, logging a user into my site, storing their information in a sql database, then looking for another person logged in and waiting to play my game. To handle the networking could I just create a sql database and use AJAX to post new information to a table that specifically handles networking?
here's a visual example of what i've been brainstorming:
[sql table: network]
[logged in user: Josh] [Josh paddle position Y]
[logged in user: Tim] [Tim Paddle position Y]
Use Ajax XMLHttpRequest to post Josh paddle position Y and Tim Paddle Position Y
to the network table, updating each client's screen accordingly (maybe use XMLHttpRequest.responseText to get the other person's information)
delete network table when both users have left the game
Anyway if you don't think this method would work, could you point me in the right direction maybe? I'm still very new to web programming, so maybe i've miss understood the way Ajax works. How is networking normally done when it comes to web applications?
There are several problems with your approach:
Can you update paddle position as fast as user moves it? Network communication have lags, DB requires time to update it's data.
Even if for few users it isn't such a problem, for many people it will become really painfull to handle with all this amount of user's requests.
How do you notify one user about another one actions? In your scheme you should ask server very frequently to get updates. This increases overall load.
The solution could be a peer-to-peer connection, but JS doesn't support it for now.
To post updates and get notified about them you can use persistent connection: instead of reestabilishing connection on each query you just do it once and then use it for bidirectional communication. Additional benefit from this is escape from need of polling server about updates.
See a Server push article on Wikipedia.
Also using DB may be unresonably costly. In fact for each game all you need is several variables that will be deleted when connection will close, so you can just store them in memory.
Sorry for the somewhat confusing title. Not sure really how to title this. My situation is this- I have an academic simulation tool, that I in the process of developing a web front-end for. While the C++-based simulator is computationally quite efficient (several hundredths to a tenth of a second runtime) for small systems, it can generate a significant (in web app terms) amount of data (~4-6mb).
Currently the setup is as follows-
User accesses index.html file. This page on the left side has an interactive form where the user can input simulation parameters. On the right side is a representation of the system they are creating, along with some greyed out tabs for various plots of the simulation data.
User clicks "Run simulation." This submits the requested sim parameters to a runSimulation.php file via an AJAX call. runSimulation.php creates an input file based on the submitted data, then runs the simulator using this input file. The simulator spits out 4-6mb of data in various output files.
Once the simulation is done running, the response to the browser is another javascript function which calls a file returnData.php. This php script packages the data in the output files as JSON data, returns the JSON data to the browser, then deletes the data files.
This response data is then fed to a few plotting objects in the browser's javascript, and the plot tabs become active. The user can then open and interact with the plotted data.
This setup is working OK, however I am running into two issues:
The return data is slow- 4-6mb of data coming back can take a while to load. (That data is being gzipped, which reduces its side considerably, but it still can take 20+ seconds on a slower connection)
The next goal is to allow the user to plot multiple simulation runs so that they can compare the results.
My thought is that I might want to keep the data files on the server, while the users session is active. This would enable the ability to only load up the data for the plot the user wants to view (and perhaps loading other data in the background as they view the results of the current plot). For the multiple runs, I can have multiple data sets sitting on the server, ready for the user to download if/when they are needed.
However, I have a big issue with this line of thinking- how do I recognize (in php) that the user has left the server, and delete the data? I don't want the users to take over the drive space on the machine. Any thoughts on best practices for this kind of web app?
For problem #1, you don't really have any options. You are already Gzip'ing the data, and using JSON, which is a relatively lightweight format. 4~6 MB of data is indeed a lot. BTW if you think PHP is taking too long to generate the data, you can use your C++ program to generate the data and serve it using PHP. You can use exec() to do that.
However, I am not sure how your simulations work, but Javascript is a Turing-complete language, so you could possibly generate some/most/all of this data on the client side (whatever makes more sense). In this case, you would save lots of bandwidth and decrease loading times significantly - but mind that JS can be really slow.
For problem #2, if you leave data on the server you'll need to keep track of active sessions (ie: when was the last time the user interacted with the server), and set a timeout that makes sense for your application. After the timeout, you can delete the data.
To keep track of interaction, you can use JS to check if a user is active (by sending heartbeats or something like that).