Is socket.io or websocket safe to use with an express server? - node.js

I was wondering to have a realtime system made with express and i came to know about socket.io and websockets. But the way they are used i.e.
const io = socket.io("https://example.com") ;
Is it safe to use. Since the url for socket connection is available at client side any third party service can enjoy and exploit the services by connecting from their service. I don't have much idea about socket.io so correct me if I am wrong.
Kindly don't mark this question as duplicate since I found a similar question but the answer to it was related to game development, here I am specific about updating clients whenever any updates are there on the server side. Clients may be website made with angular or apps made with Android studio.
Any help is highly appreciable.

socket.io is widely used. It is perfectly fine for use in production.
Regarding the authentication part, A websocket connection b/w client and browser is established via http upgrade request(in http/1.1).
If you have an authentication mechanism in place for your application using cookie and session then you should be safe. No one can establish websocket connection directly without first logging in. On top of this you can limit connection per user to ensure that a registered user cant further exploit the connection using the cookie data.

Related

Multiple Socket.io app processes cause each client socket connects and disconnects repeatedly

I am working on a nodejs app with Socket.io and I did a test in a single process using PM 2 and it was no errors. Then I move to our production environment(We use Google Cloud Compute Instance).
I run 3 app processes and a iOS client connects to the server.
By the way the iOS client doesn't keep the socket connection. It doesn't send disconnect to the server. But it's disconnected and reconnect to the server. It happens continuously.
I am not sure why the server disconnects the client.
If you have any hint or answer for this, I would appreciate you.
That's probably because requests end up on a different machine rather than the one they originated from.
Straight from Socket.io Docs: Using Multiple Nodes:
If you plan to distribute the load of connections among different processes or machines, you have to make sure that requests associated with a particular session id connect to the process that originated them.
What you need to do:
Enable session affinity, a.k.a sticky sessions.
If you want to work with rooms/namespaces you also need to use a centralised memory store to keep track of namespace information, such as the Redis/Redis Adapter.
But I'd advise you to read the documentation piece I posted, things might have changed a bit since the last time I've implemented something like this.
By default, the socket.io client "tests" out the connection to its server with a couple http requests. If you have multiple server requests and those initial http requests don't go to the exact same server each time, then the socket.io connect will never get established properly and will not switch over to webSocket and it will keep attempting to use http polling.
There are two ways to fix this.
You can configure your clients to just assume the webSocket protocol will work. This will initiate the connection with one and only one http connection which will then be immediately upgraded to the webSocket protocol (with socket.io running on top of that). In socket.io, this is a transport option specified with the initial connection.
You can configure your server infrastructure to be sticky so that a request from a given client always goes back to the exact same server. There are lots of ways to do this depending upon your server architecture and how the load balancing is done between your servers.
If your servers are keeping any client state local to the server (and not in a shared database that all servers access), then you will need even a dropped connection and reconnect to go back to the same server and you will need sticky connections as your only solution. You can read more about sticky sessions on the socket.io website here.
Thanks for your replies.
I finally figured out the issue. The issue was caused by TTL of backend service in Google Cloud Load Balancer. The default TTL was 30 seconds and it made each socket connection tried to disconnect and reconnect.
So I updated the value to 3600s and then I could keep the connection.

Difference in socket.io client behavior for browser vs server

I am wondering if someone has used the socket.io-client library for communicating between servers instead of communicating between browsers to server.
Is this kosher?
Is the behavior of the library pretty much the same when the client library is running on a server vs running in the browser?
Can the socket.io-server library initialize connections with clients, or do socket.io-clients need to initialize connections?
Is this kosher?
Yes, that is exactly what the socket.io-client is designed for. It works great for communicating between two servers.
Is the behavior of the library pretty much the same when the client
library is running on a server vs running in the browser?
Yes, the behavior is identical. The only difference under the covers is that the browser implementation is built on top of the browser's webSocket support whereas the server-side client uses the socket.io webSocket implementation.
Can the socket.io-server library initialize connections with clients,
or do socket.io-clients need to initialize connections?
Only socket.io servers are "listening" for incoming connections. Somebody has to connect TO the socket.io server. You can't connect TO a socket.io client. A client must connect to a server. So, a socket.io client (which can be either in a browser or on a server) must be the one that creates the connection. Once connected, data can be sent either way on that connection.
Considering you are talking about the JavaScript version of the socket.io-client:
Yes, of course it is legitimate to use it server-side. it is just a "client" library, not only a "client-SIDE" library.
The behavior is the same, yes.
Clients need to initialize connections.
There is a server side usage example the Socket.io-client documentation
Other versions of the socket.io-client are also available in different languages (swift, java, CPP), that you can find on their Github page.

How to scrape socket.io updates to a third-party site?

I basically want to know if its possible to use Socket.io using the server-side only with no client side? BUT I want to know if my server-side can instead connect with a different site that I cannot use Socket.io to connect to.
Use PhantomJS to load the third-party site and then inject your own javascript into the page to catch events and send those events back to your own server.
socket.io is a two-way connection. Client <--> Server. You must have a socket.io endpoint at both ends to even establish a connection in the first place. And, then once you establish the connection, you must have agreed upon messages that can be exchanged between the two ends for it to do anything useful.
It is not useful to have a server-side socket.io that doesn't actually connect to anything and nothing connects to it. It wouldn't be doing anything, just sitting there waiting for someone to connect to it.
It is possible to have two cooperating servers connect to one another with socket.io (one server just acts like a client in that case by initiating the connection to the other server). But, again both endpoints must participate in the connection for the connection to even be established and certainly for it to do anything useful.
If you just want to download the contents of a site for scraping purposes, then you would not use socket.io for that. You would just use the nodejs http module (or any of several other modules built on top of it). Your server would essentially pretend to be a browser. It would request a web page from any random web server using HTTP (not socket.io). That web server would return the web page via the normal HTTP request. Your receiving server can then do whatever it wants with that web page (scrape it, whatever).

socket.io without running a node server

I have a web application that requires PUSH notifications. I looked into node.js and socket.io and have an example that's working. The question I have is, Is it possible to use socket.io only in my client side JS without running a node.js server?
Can a third party server just send requests to a proxy server and may be socket.io just listens to a port on the proxy server and sends back events to it?
Thanks,
You need a server side technology to send data back and forth via web sockets. Socket.io is a communication layer. Which means, you need to have a server side method to send data.
However,
You can use various third party services to use web sockets and notifications. They are relatively easy to use, and they have support for many other languages.
Check some of these out:
http://pusher.com/
https://www.firebase.com/
http://www.pubnub.com/
https://www.tambur.io/
https://fanout.io/
You don't need to run Node.js to have a real time push notifications. You can use a third party service that does it for you. Most of them are cheap, sometimes free for low traffic instances.

Socket.io Security Issues

I'm wondering how I could secure my socket.io connection to the server from th following.
Security Issues:
What would stop malicious users from connecting to the socket server via client side code?
Example:
OUTSIDE DOMAIN REQUEST var socket = io.connect('http://Mydomain', {port: 4000});
Users can seemingly create thousands of concurrent connections just by opening a different browser window.
How can I prevent these issues?
You should be able to check serverside that the HTTP referrer is correct. Check the socket.io spec for info on both http referring as well as handshaking.
https://github.com/socketio/socket.io-protocol
Also 0.8 has referrer verification. Havent used it before, but this may be a place to start looking:
https://github.com/LearnBoost/socket.io/pull/481
Well, if your (real) clients are coming from a well know location, you'd probably want to to block everyone else at the firewall level. Assuming your service is available to everyone, you can probably look into client-server handshake mechanism.

Resources