How does a server verify a client in a mulitplayer game? - security

So tons of games are run via custom clients (call it game.exe) but must communicate to a server. How does the developer ensure that only connections from the custom client are accepted and not any other requests, say from a web browser?
Ex: I play game.exe and my requests go thought no problem. I then submit a request to that game server using my web browser or some other POST utility, but it is ignored by the game server to prevent cheating.
Is this done via secret strings that are coded into game.exe and sent with every request? It seems to vulnerable to intercept them with a packet sniffer. Same applies with a client-side SSL certificate, someone could easily find the key file in the game files and forge requests.

Typically games that are stand alone applications - with a .exe extension on Windows, for example - do not use http as their protocols, unlike web browsers.
Irrespective of the protocol used, however, games typically send credentials - often account credentials, similar to a user name and password - when the connection is established. Many games uses a persistent TCP connection, so this only had to be done when logging in to the game.

Related

How to use a secure WebSocket-Connection for a local client

I need informations about security risks and proof of concepts to work with an local client.
In my option, a user will install two components:
The game client
The client launcher
The launcher is running as an background process all the time. The launcher provides an WebSocket server.
The user will open my website to start the game (with game-server lists and other settings). The Website connects to the game launcher to handle all actions (change configuration, start the game executable)..
Problem:
How realize the communication with the website and the game launcher? Okay, Websockets, yes. But browsers forbid to connect to localhost/127.0.0.1 by security reason.
An fake-pointer as DNS or hosts-file to an subdomain like local.game.tld is bad, because SSL-Certificates can be revoked here as bad usage.
Another idea was to provide an NPAPI-Plugin for the browser. But it seems, that the NPAPI is deprecated and useless for the future.
Whats the best practice to communicate between webpages and local installed software?
But browsers forbid to connect to localhost/127.0.0.1 by security reason
This isn't true. Browsers allow you to connect to localhost / 127.0.0.1. I do it all the time on my machine.
The issue is that TLS (wss://localhost, not ws://localhost) requires a certificate and browsers forbid mixed content (you can't have an https website load non-encrypted resources).
fake-pointer as DNS or hosts-file to an subdomain like local.game.tld is bad, because SSL-Certificates can be revoked here as bad usage.
As part of your game installer you could create a hosts file entry with a certificate for mygame.localhost (possibly using a local script) and then ask the player to authorize the installation of the certificate using their password. This way your certificate won't be revoked... but you are right that this his suboptimal.
EDIT: also, please note that the domain name must be at the end, not at the beginning (i.e., game.localhost and not localhost.game).
Whats the best practice to communicate between webpages and local installed software?
Generally speaking, if your game is installed on the local machine, there's no need to encrypt the communication between the local browser and the local machine.
You can easily write your local server to accept only connections from the local machine (or, at worst, if need be, accept connections from the local area network - though this adds security risks).
Your webpage and WebSocket data can be sent "in the clear" (ws:// and http://) between the local server and the browser since they are both on the same machine - this way you don't need a browser. The local server would initiate (as a client) any encrypted connection it needs when communicating with an external service (was:// / https://).
EDIT (from the comments):
There are the only 2 solutions I know of:
Installing a self-signed certificate; or
Using http instead of https and having the server handle outside traffic as if it were a client (so all traffic going outside is encrypted).

Why do browsers forbid non-SSL connections when a webpage was already served over HTTPS?

Once a webpage is served over HTTPS, we can be fairly certain that they are who we intended.
At this point, the only security risk left is that the website itself is malicious or has a security vulnerability.
For example, you may enter your credit card details which are sent to their server, and their server could release those details to the public.
I'm now trying to figure out the reasons why browsers do not allow non-SSL connections when the webpage was already served over HTTPS?
For example, browsers will stop allowing non-SSL HTTP and WS content, and don't expose UDP or TCP socket APIs.
To me there is the exact same risk that they don't use SSL on their server anyway. If anything, HTTPS could now be giving a false sense of security.
I could only identify two reasons:
To prevent webpages from accidentally using non-SSL connections. So I can understand that a form or image should only allow HTTPS. But I believe that browsers should allow, for example, UDP sockets but must be created like so (confirming that the programmer is aware of security risks):
udp = new SomeBrowserAPI.CreateUDPSocket()
udp.amAwareThat("Nothing is encrypted over UDP and I should not send any sensitive data here")
udp.amAwareThat("I cannot confirm the identity of who I am sending data to or receiving data from")
A client-side developer should not have to worry about security risks, but rather UI etc. By being forced to communicate to the server over SSL, it is up to the backend developers to worry about security only. However, this is already not the case anyway. If you are a client-side developer, you could easily write malicious client-side code that reads password input and sends it to your own server, as long as your own server is also over SSL (although SSL might at least allow you to identify who was responsible).
Are there any other reasons? Are my reasons / solutions / info correct?
There is a basic post in Google's Web Fundamentals: What is mixed content?
It is very basic, but lists three major threats: data authentication, data integrity and data confidentiality.
When you connect over UDP, you don't know
who actually serves your connection. It might have been intercepted by enemies;
whether the data received is actually the data sent. It might have been tampered by a man-in-the-middle;
who else have read your messages. Big brother is watching you.
Mixed content ruins the concept of secure webpages.

Use Electron-App (displaying an online Website) as a secure proxy to the local network

I've build a Web-App that is displayed in an Electron-App with Nativefier. That already works great, but now i need to send requests from the website to the local network to talk with some local devices which are (with it's ip-address) configured in the Web-App.
I had the idea to use the Electron-App as a "proxy" to the local network by using a javascript callback from the Website to the Electron-App (don't know if this is possible, just an idea), which then makes the local request because it's running on a computer in the same network.
The reason for this post is that i need ideas/tips to secure this and prevent allowing to talk to other than the desired Web-App (available under a certain domain) by developing something protective like checking or validating the Server, validating the request by sending it's hash back to the server or other methods.
So my questions are: is it generally a good idea to do something like this or is this a huge security problem and have anyone any tips to secure the communication and only allowing the communication to in the web-app configured devices in the local network?

How to access TCP Socket via web client

I have a program in an embedded device that outputs an xml string to a socket. The embedded device has lighthttpd has a web server. I want to use a web based client (no flash/silverlight) to connect to the socket and pull the xml data every second.
I looked at Node.js with Socket.io to get what I want to do, but I am not clear about how to proceed. Searching through the Node.js and Socket.io documentation and examples I see standard client-server behavior, nothing regarding what I am trying to do.
Basically, the web server is just there to accept a connection from a client on the socket that the embedded application is outputting data to. Basically the web server's purpose is to just let the client retrieve data from the raw tcp socket that the embedded application is writing to. Please advice.
I solved the problem using Websockify, which acts as bridge between a TCP Socket and a browser.
The html client will connect to a websocket, and Websockify will listen on the websocket port and transmit data between the websocket and the tcp socket.
Web browsers have the ability to do HTTP requests (which can be web page requests or Ajax requests for data) and webSocket connections. You will need to pick one of these two mechanisms if you're sticking with stock browser access.
If the lighthttpd web server in the embedded device does not support webSockets, then your choice will like be an Ajax call from the browser to your server. This is basically just an HTTP request that make return something different than a web page (often JSON data) and is designed to fetch data from the server into a web client.
If the lighthttpd web server does support webSockets, then you could use a webSocket connection to fetch the data too. This has an advantage of being a persistent connection and allows for the server to directly send data to the client (without the client even requesting more data) whenever it wants to (more efficient for constant updates).
An Ajax connection is generally not persistent. A client sends an Ajax request, the server returns the answer and the connection is closed. The next request starts a new Ajax request.
Either Ajax requests or webSocket connections should work just fine for your use. All browsers still in use support Ajax. WebSockets are supported in modern browsers (IE10 and higher).
Once you decide upon a client connection strategy, then you'd build your web app on the embedded device that served as the middleman between the browser and the data on the embedded device. It would collect the appropriate data from the embedded device and then be able to send that to browser clients that connected and requested the data.
I'm not sure exactly why you mentioned node.js. In this circumstance, it would be used as the web server and the environment for building your app and the logic that collects the data from your device and feeds it to the requesting web browser, but it sounds like you already have lighthttpd for this purpose. Personally, I recommend node.js if it works in your environment. Combined with socket.io (for webSocket support), it's a very nice way to connect browsers directly to an embedded device. I have an attic fan controller written in node.js and running on a Raspberry Pi. The node.js app monitors temperature probes and controls relays that switch attic fans and node.js also serves as a web server for me to administer and monitor the node.js. All-in-all, it's a pretty slick environment if you already know and like programming in Javascript and there's a rich set of add-in modules to extend its capabilities available through NPM. If, however, your embedded device isn't a common device that there is already support for node.js on or it doesn't already have node.js on it, then you'd be facing a porting tasks to make node.js run on it which might be more work than using some other development environment that already runs on the device like lighthttpd.

Is it a good practice to use Socket.IO's emit() instead of all HTTP requests?

I set up a Node.js HTTP server. It listens to path '/' and returns an empty HTML template on a get request.
This template includes Require.js client script, which creates Socket.IO connection with a server.
Then all communication between client and server is provided by Web Sockets.
On connection, server requires authentication; if there are authentication cookies then client sends them to server for validation, if no cookies then client renders login view and waits for user input, etc.
So far everything works, after validating credentials I create a SID for user and use it to manage his access rights. Then I render main view and application starts.
Questions:
Is there a need to use HTTPS instead of HTTP since I'm only using HTTP for sending script to the client? (Note: I'm planning to use Local Storage instead of cookies)
Are the any downfalls in using pure Web Sockets without HTTP?
If it works, why nobody's using that?
Is there a need to use HTTPS instead of HTTP since I'm only using HTTP
for sending script to the client? (Note: I'm planning to use Local
Storage instead of cookies)
No, HTTP/HTTPS is required for handshake for websockets. Choice of HTTP or HTTPS is from security point of view. If you want to use it for simply sending script then there is no harm. If you want to implement user login / authentication in your pages then HTTPS should be used.
Are the any downfalls in using pure Web Sockets without HTTP?
Web sockets and HTTP are very different. If you use pure Web Sockets you will miss out on HTTP. HTTP is the preferred choice for cross-platform web services. It is good for document traversal/retrieval, but it is one way. Web socket provides full-duplex communications channels over a single TCP connection and allows us to get rid of the workarounds and hacks like Ajax, Reverse Ajax, Comet etc. Important thing to note is that both can coexist. So aim for web sockets without leaving out HTTP.
If it works, why nobody's using that?
We live in the age of HTTP, web sockets are relatively new. In the long term, web sockets will gain popularity and take up larger share of web services. Many browsers until recently did not support web sockets properly. See here, IE 10 is the latest and only version in IE to support web sockets. nginx, a wildly popular server did not support web sockets until Feb-March 2013. It will take time for web sockets to become mainstream but it will.
Your question is pretty similar to this one
Why use AJAX when WebSockets is available?
At the end of the day they were both created for different things although you can use web sockets for most, if not everything which can be done in normal HTTP requests.
I'd recommend using HTTPS as you do seem to be sending authentication data over websockets (which will also use the SSL, no?) but then it depends on your definition of 'need'.
Downfalls - Lack of support for older browsers
It's not used this this in many other situations because it's not necessary and it's still 'relatively new'.

Resources