Is WebRTC cheat-proof for multiplayer HTML5 game? - javascript

I'm creating a multiplayer HTML5 P2P game; and I would like to use WebRTC to communicate without the server.
I know that there is no way to prevent from JS modification from the browser, but anyway, I would like to know : is WebRTC secure enough ?
Can a user can modify on-the-fly what the packet contains ? Or does DTLS+SRTP prevent from that ? If I communicate with another player, how can the user B be sure that the packet has not been modified since it has been written ?
I would say that it is, because TLS involves that there is Diffie-Hellman key-exchange; and all the communications should be AES + signed with SHA. So I'm guessing that is secured.
Am I wrong ?

Can a user can modify on-the-fly what the packet contains?
No.
Or does DTLS+SRTP prevent from that? If I communicate with another player,
how can the user B be sure that the packet has not been modified since
it has been written?
Yes.
However, if you don't trust A you cannot trust what he did write.

Nothing on the client is cheat-proof. Keep in mind that the browser is just a means for users to send messages to your server (or to other users in your case). A determined malicious individual could fabricate the messages himself without a browser.
Encryption exists to prevent a third party from reading/altering messages sent between two individuals. It can in no way prevent one of the two individuals from sending other messages than you intended and correctly signing them.
What you can do is validate on each client that the messages received from the other "make sense", that they fit in the context they are received in. A trivial example would be a chess game where a player sends a message that would teleport his piece in a place where it cannot legally move. In this case if both players know the state of the game (necessary i think), then the second player can and should determine that the move was invalid and somehow respond to that (either terminate the game or attempt to recover from the invalid state).

Related

Websocket : Get information from Web socket server

I am very new to websockets and trying to create an omegle as an example. A centralized chat server to which every client can connect through a websocket and the the server matches people based on interests. The people can chat through the websocket connection thereafter.
I am just curious about one thing: Once my site goes live and different clients keep connecting, essentially in the background they are connecting to my central server through the websocket. Can't any client run javascript on its chrome console and inject a malicious script or get access to the clients connected to the server already since the connection has been established and its a stateful connection? I am not sure if there is a way to do that. And if there is, what security mechanisms i need to take care of?
The response to your question is "Yes" and "No"!
it depends on so many things. First, is your chat a public one? I mean can every body join the chat room without login?
In this case i guess everybody can chat so a guy who want to use your websockets can do so a it is public.
In the case your chat is private it is your own to protect your websockets events from being accessed by everybody. This start by registering users after a robust login process.
As all others Internet (and computer based) tech, websocket is subject to hacking. You chould protect your websockets as you protect your web based developments.
Typing "websocket common attacks" in Google will return you links that talk of websocket security.
Yes, a client can definitely inject a malicious script... but it will only affect the client's own browser.
No. There isn't a way to do that unless you explicitly created a vulnerability.
You see, first of all, websockets are not peer-to-peer connections. They require a server to transmit messages between end users, so if the server doesn't do anything about an incoming message request, the user the first user intended to send a message to would not receive anything. Essentially, this means that websocket clients can only connect to users if the server lets them.
However, even if websockets were p2p connections that would still not be possible, or what kind of a web would we have?! I hope you understand that any data sent to a client isn't automatically executed as code. It usually is in a string format and it will never be able to run any code unless you actually eval it or something. (Or you forget about XSS and don't properly escape data that would be rendered as HTML.)
So, to answer your question, no and no. Security measures? Don't eval incoming data.
However, what you do have to be aware of in websockets is that any client can connect (well, at least try) to a websocket server. See, because websockets usually are used to send data between clients, when a server receives a message, it usually will broadcast that message to everyone in that connection/room except for the sender. This means that a user with malicious intent may enter your room and send data, as well as receive data that's probably meant to be private.
To prevent this, ensure you are setting up proper authentication. You can do this through cookies, perhaps, used with session or JWT (I usually use the latter). When a user joins a room or connects, check if that user is authorized and allowed to be in the room. Otherwise, reject the connection.
Here's a bit broader explanation that might help you.
Web sockets work on TCP connections. That means the socket connects to a specific destination and transmits data ("messages"). Those messages can flow both ways (in and out). Users connect to your server using clients (most commonly a browser).
The connections are unique, meaning no two clients share the same connection. Therefore, no one else knows what others send to or receive from the server.
Messages can be of various types, but the most commonly used is a string. Typically people encode some JSON objects in those strings to perform specific actions. Something along the lines of:
{
message: "Hello!",
channel: "general"
}
Now here comes your role. How to act on those messages, and what to send to whom. Standard libraries provide functionalities like targeting a single socket or sending messages to many sockets. Imagine it like a list of connections. They can send specific commands to join/leave channels, so you add more meta data to each. In the previous example, you might want to send Hello! to every connection that has "joined" a channel (by sending a specific command to do so).
You decide what the commands are:
{
command: "join/leave",
channel: "general"
}
You might want to spread every message you receive to others or keep it to yourself (and execute some custom functionality). Nothing happens out of the box - the server receives the message, and that's it.
All of the above means that whatever users do with their clients won't affect you or others. The only way you can know of their actions is if they send you a message. Those messages you must be careful with, as they can contain any malicious code.
Therefore I'd highly recommend you use some library that deals with web sockets in case you'd like to ship something to people. If it's for learning purposes - stick to the plain functionalities.

Vue.js to Node.js Server: How can I secure my POST call?

I have a simple single page application (a game) written in Vue.js with a backend in Node.js, all hosted on Heroku. My frontend in Vue uses axios to do the api call to my backend, which uses express and mysql libraries to query my database and get high scores or post a new score.
I gave the finished game to my friends and they realized right away they could use postman or similar to do a simple post request and send a fake score, so I'd like to secure it.
I'm open to anything fairly simple, but I'd like to set a token that I can check in my Node.js if it matches, and if not, send a 403. I've tried setting an environment variable with a token, but on the front end ends up displaying that token in the resources if I inspect the element (if I use a .env file and then get the value). I've also tried my config.json files, but obviously there's no way to hide these values from anyone using inspect element. I tried checking the req.hostname but even when I send a request from postman, it returns a 200.
How can I secure my post request?
Problem
As others have pointed out, there is no generic way to generate information client side that cannot be forged. The problem being that no matter how complex the rules to generate this information (e.g. game scores must be prime numbers), somebody might isolate those rules and create arbitrary information (e.g. fake prime number scores without playing the game).
For games this often leads to input processing (client) and game rules (server) being split between client & server, making it impossible to isolate score generation from game rules. However this introduces latency and asynchronicity and requires heavy refactoring for client side games - three difficult issues.
Solution
There are scenarios where a different solution exists. Take chess: given a chessboard ask the client for the least possible number of moves until mate. The number of moves is the score and the lowest score wins. The client must send the specific moves and the server verifies the result. In other words the client side information is the entire input the player generates for the game.
As generic pattern this means: define the client side (score) information as entire game input. Record the entire input client side and re-run the game server side with this input. Verify the result.
Requirements:
Split input processing from game rules so that it can run with pre-defined input.
Implement equivalent server and client side game rules.
Eliminate any source of randomness! (E.g. use the same seed for the same random number generator or a server generated random number list)
You are close to this solution as you have wisely chosen one language for server and client, and Javascript represents numbers as plattform independent 64-bit floats (which avoids rounding errors). This solution avoids latency & asynchronicity, but does not allow multi-player games where atomic server side updates and coupled player input is needed.

HTML5 game connecting to database safely (stopping manual JavaScript by user)

I'm using HTML, JQuery and PHP/MySQL. I understand for the most part that if I want to make this game safe then the server needs to do practically everything, but in some situations the game must tell the server to do things. In my case this is a RPG type setup, it will need to at times send a POST request to a PHP script via an Ajax call that updates, inserts or deletes from the database. Such as a player wins a battle and he's exp needs to be appended to, or a player takes a turn in a battle and it needs to work out the amount of HP taken off the other enemy and return it as well as updating the enemy's HP.
Lets say when the player clicks "Attack" and it runs a JavaScript function called playerMove('attack'), what stops the user going into their browser developer tools and running this function manually? Or using similar code on an alternative server and running cross site Ajax calls to the same public scripts on my server?
Is there any way around this problem? Even if I had a game that was made as a client side application (Like C# or whatever) wouldn't these problems still exist, but just harder for users to execute. Or would connecting to MySQL directly through C# be mostly safe if done correctly. But what about C# sending POST requests to PHP scripts, wouldn't that bring you back to the problem that as the scripts are public they could be POSTed to from other sources?
Basically, every time a player "attack" request comes in, the server needs to do at least the following:
Do basic validation on the data in the request.
Check that the subject player attack request is actually coming from the correct account.
Check that the player is currently in battle, it's his turn, the target of the attack is valid, the player doesn't have any status effects preventing attacking, etc. Any game logic that prescribes that the player can't attack right now.
Calculate the attack's effects.
Update the database.
Return the results to the client.
Return the results to all other clients, through long polling, WebSockets, etc.
Now, if the player tries to make the AJAX call when they shouldn't be able to, your server validation should prevent it. Remember, the client is all input/output and can't do any game logic without tons of code duplication between your JS and PHP.
Making a game in PHP, especially multiplayer, requires a ton of overhead and boilerplate. I'd honestly think about using another language/framework. For example, Meteor hooks up a lot of this stuff for you. Client, server, and database data are automatically synchronized. It also has latency compensation so the client can run the server code to get an expected result, and then update to the actual result whenever the server eventually responds. This would make your game feel like it's working in real time, while still giving the server the last say on whatever game logic happens.

voice activity detection within the browser

So this is a tricky one.
I wish to write a web application which records a word said by the user, and then sends the samples to the server side for processing.
The algorithm I have in mind is as follows:
start a recording session once the user has clicked on a button
wait for the user to have said a single word (assuming he know he's supposed to say a single word)
stop the recording once he said it
send the samples to the server, say using HTTP
process the signal on the server side
send some response back to the user.
There are several solution for Voice Activity Detection in Java,C#, and other high level languages I presume.
However, I wish this part would to be done on the Client side (otherwise, I'll have to send too much data from the client to the server which is highly inefficient) I.E in javascript and HTML5.
I'm not an experienced web developer, so my questions are:
Is this feasible? Is there a library for that (I haven't found any)?
What would be the best approach in approaching the problem?

Does using node.js for comet like behaviour pose a security threat?

I am looking atways of implementing comet like behaviour for a website. So far Node.js (and its various derivatives) seem to be ahead of the rest of the field (IMHO).
However, I can't help noticing that with all of the client side JS that is responsible for updating the client (browser etc), the communication port is visibly hard coded in the client script.
To me (and I may be wrong), that is just like publishing which ports of your server are open (and therefore welcoming hackers to attack through that port). Am I being overly paranoid or is this really a cause for concern?
I really want to say Comet isn't any less secure, but that's not quite true.
First, the reason why it's generally no less secure is that Comet requests are just like regular HTTP request, but with a slightly longer lifecycle. So they're subject to the same requirements for proper security as any other HTTP endpoint you write (e.g. make sure you authenticate the user's session cookie, etc.)
But that long life cycle means it's possible for the underlying user to change mid-stream through a Comet connection. This can make for some problematic user experiences. For example, imagine a chat application that uses Comet streaming to send messages to the browser, and uses regular HTTP polling to update the buddy list, showing which friends the user has online. Now examine this scenario ...
Fred logs into your comet-based chat app in window A. You open a Comet connection (authenticated as Fred), and start pulling messages for him. Cool.
Now Fred minimizes the window and (thinking he's closed everything) walks away
Sally comes along (not seeing Fred's minimized window) and opens a 2nd window onto your site and logs herself in. This invalidates Fred's session cookie, and replaces it with Sally's.
Not too long afterwards, unseen by Sally, that first window polls the server to see which friends of the current user are online. Because the current user is now Sally, that first window updates to show all her friends.
... now what does Sally see when she finds that first window? The friend list has updated to show all her friends, so it looks like she's logged in there. But Comet connection was authenticated to Fred and is still open. So Sally is getting Fred's messages, and not getting hers. Ewww.
This is the sort of thing you need to watch out for rather than worrying about how visible your endpoint is. All http endpoints are visible, and can be easily reverse engineered using modern browser debuggers and network packet sniffers. Security comes from implementing sane authentication strategies on the server, not from hiding how you connect to the server.
Finally, note that nothing in your question or this answer is specific to node.js. All Comet solutions have these same traits.

Categories

Resources