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.
Related
I'm writing a TCP server application using NodeJS. However, each socket runs on a separate child-process (server.on("connection")). To send messages to specific clients, I used Emitter, and each socket generates its own listener (on clientID). So if there are 10000 connected devices, the application will create 10000 listeners. This looks terrible. What dangers will this pose? I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code.
Update:
Have any idea to send message to specific client without add custom listeners?
However, each socket runs on a separate process.
Why would you do that? The core idea behind NodeJS is to run things in an event loop. Single threaded, yes, but asynchronous.
This looks terrible. What dangers will this pose?
It is terrible. The biggest issue is that you sacrifice a lot of resources. You not only spawn thousands of processes but you also spawn lots of emitters. So first of all this means lots of RAM eaten. Secondly this means degraded performance due to process context switch, which typically is slower than user space switch. Assuming your machine will even allow you to spawn so many processes.
I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code.
I assume you have a TCP server, two connected clients and client A wants to send message to client B. Is that correct? TCP by itself won't do that for you. You need some protocol on top of it. For example:
Client connects to the server. At this point the client is not logged in and cannot do anything except for authentication.
Client authenticates. It sends (username, password) pair to the server. The server validates the pair. The server keeps a global mapping {"<username>": [sockets]} and adds newly authenticated client to that mapping.
Client A wants to send a message to client B. So it sends data of the form {"type": "direct", "destination": "clientB", "data": "hello B"}. The server parses the message and forwards it to the appropriate client (taken from the global mapping).
In case when you want to broadcast the message you send say {"type":"broadcast", "data": "hello all"} kind of message. The server then parses it, it loops through all connected clients (found in the global mapping) and forwards the message to each client.
Of course you also need some framing of packets. Since TCP is a stream, then it doesn't really understand messages and where one starts and the other ends. Dumping things to JSON is a half of the problem. Because then you have to send this JSON over the network and the other side has to know how many bytes it has to read. One way is to prefix each message with, say, 2 bytes that tell the other side how long the message is.
Btw you may want to consider using socket.io (or some other lib) that take care of some of those tedious details for you.
I am adding a WebSocket handler to my Azure Webapp. Lets say that I am writing chat server (though I'm not), where the server will keep a list of all open connections in memory so that all connected clients can talk to each other.
Now, I have auto-scaling turned on so my server can some point in time scale out to 2 instances. Now clients connected to instance 1 cannot talk to clients who happen to be connected to instance 2.
To solve this I am trying to find out if it is possible to target a specific instance using Azures ARRAffinity cookie, but what I found so far, this is only possible:
For ordinary web requests (not "new WebSocket()")
From server to server using node.js
So my question, is it in fact possible in some way to this with websockets? Do you have some other suggestions?
EDIT 2017-11-02: This is still an interesting question, but I have solved it in a different (mostly positive) way: Since all messages going through the websocket is already serialized, it was easy to utilize my already present Redis cache publish/subscribe functionality.
So what I do now is:
Message comes through websocket from client A - targeted at client B.
Message arrives at webserver X (one of many possible webservers depending on scale out)
Message is published to a Redis cache channel
All webservers subscribes to Redis cache channel and receives the message
The one webserver who happens to hold a websocket connection to the target client delivers the message, all other webservers ignore the message
I have PHP on the server side, and HTML and javascript on the client side.
I am making an app where a stakeholder types a message that is broadcasted to multiple recievers of a group in real time.
I did some research on google and I understand I need to use WebSockets or Comet for real time push notifications. Is WebSocket or Comet mandatory for sending mass notifications to users?
Is my understanding correct? Any references to start with?
If the client is a browser, then the ONLY two ways a standard browser can connect to a server is via an Ajax (e.g. http) request or a webSocket connection. So, if you want a client to get notified of something from the outside world it has to use one of those two mechanisms.
HTTP requests are transitory. The client makes a request of a server, the server responds. HTTP requests are perfect for the client requesting information from the server. They are not very good at the server sending information to the client because normally the client is not connected. There are hacks and work-arounds where the client "polls" the server on some interval and maybe even the server uses longer running requests to try to simulate a "push" type system, but they are sub-optimal hacks at best.
webSockets are continuous connections. The client connects and the connection remains in place for as long as both sides want. This allows either side the ability to send a message to the other side whenever they want. That means the server can "push" data to the client whenever it wants. webSockets are efficient for push connections and are recommended (this is one of the main things they were designed for).
Comet is a library that was originally built for using HTTP to try to "hack" or "simulate" push before webSockets were invented and then before they were widely supported. I can think of no reason why one would want to use Comet instead of a webSocket unless you had such an old browser that webSocket was not supported.
So, if you are trying to do "realtime server push" to a browser, then you must have a continuously connected socket from the client which means webSocket (or something built on top of webSocket like socket.io).
For phone apps where you have access to the phone SDK, you can use the "push" system built into the OS to push some messages from server to client. This isn't quite the same as the two way webSocket channel, but since you asked about "push notifications", the OS push services available in both Android and IOS could also be an option for pushing notifications from server to client. Here's info on iOS notifications and Google Cloud Messaging
As of 2016, one can also use Server-sent events in all modern browsers except Microsoft browsers (not supported yet in Edge or IE) to push data from server to client. Here's a browser compatibility table. Server-sent events use a long lasting HTTP connection, a special MIME type and a supporting client in order to be able to send events from server to client at any time. Unlike webSockets, server-sent events are one way only (from server to client). A client would then use a traditional Ajax call in order to be able to send data to a server (whereas with a webSocket data can be sent either way over the same webSocket connection).
Here's a good description of how server-sent events work: How do server-sent events actually work?
Is your client application a SPA? (Single Page application)?
It's very important because if not, you have to consider that everytime a client change page, connection with websocket server will be lost.
In this case you have to manage a queue because if stakeholder send a multicast request when one client is disconnected, client won't receive nothing.
Polling won't solve this situation too and it's an orrible solution because mobile clients (for example) with typical internet plan, will consume megabytes for unuseful "ping" traffic.
A real example of polling is a child in a car asking his dad every minute if they are arrived to a destination!
So, Is there a solution without using spa?
Yes, using a "shared storage" between stakeholder and clients, and using websocket only for "wake up" online clients saying: Hey there is something new, go to check!
Everytime a client open a page it will receive from backend also not-read notifications, taken from the storage.
When a stakeholder want to notify something, it will just store the notification message in the shared storage and send a "pulse" to notification server.
Notification server will forward the "pulse" to online clients (just in case someone is stuck reading a page).
If a "pulse" is lost because a client is changing page there is no problem because the client will bring notifications from the storage.
Every page will contain this logic:
Retrive number or unread notifications (server side)
Connect to the notification server after 5 seconds (javascript side).
Hope it helps.
I would suggest that using webSockets is a more efficient way compared to other options, why is this? Well when a client receives a notification that there's a change in the server there is no need to create an AJAX call to the server to get that change, it can be sent to the client with the same webSocket connection more easily than AJAX. This means efficient code and a faster running App!
What would be best mechanism, for achieving ability, for users, that are logged in, receive messages, generated by server. As there is no way for a server, to send information to user, when it has new message to deliver, a user browser should poll with some specific interval, to receive in response new messages, additionally, there should be a way for server, to not send messages, that are already delivered to user. You could draw a connections with something like public chat mechanism, but the thing I need is message delay as close to realtime and ability to handle about 100 users simultaniously, making least traffic possible. Additional note: data is needed only when user is online, no need to store that data in server, for other users to read "history".
In my mind, there are one way of achieving this - global "message box" where server puts all messages, user browser is constantly polling the server, to check, if last received message ID is equal to last message ID in message box.
The question is, if this is right way to do that, or there are another ways for such tasks, as need for realtime data can be found everywhere: sensor data, multiplayer games, chat, stock market and more...
XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)
https://github.com/ssoper/jquery-bosh
Build a web-based notification tool with XMPP
Write real-time web applications with XMPP, PHP, and JavaScript
Hope this helps.
Isn't pushing a better strategy? Keep a tcp connection open between server and browser and stream changes to the browser when new information is available.
Take a look at html 5 websockets. (which does exactly this)
heres a demo
Have you looked at Comet?
Comet is a web application model in
which a long-held HTTP request allows
a web server to push data to a
browser, without the browser
explicitly requesting it.
If you search stackoverflow there is plenty of info about its use.
I write a browser game (php, javascript) and I do not know how to make a callback. necessary that the server itself
found a client and call the function (only had one)
Don't write a browsergame if you don't know the basics! Browsergames are way too complex to learn programming.
If you want to make the server notify a client about something you will need to keep a connection open (search keywords: COMET, long polling) as you cannot initiate connections from the server to clients.
For this I can suggest you using Firebase. It is a API that let you to add cloud Data management that your user clients do. You can use that communication to search for client.
If I understand your question, what you need is a socket. Since you're using PHP and Javascript, a WebSocket might be just what you're looking for. With WebSockets, the connection between the client and the server is persisted, so the server can just push data/messages to any or all of the clients connected to it at any point in time. Likewise, the any client connected to the server can push messages/data up to the server.
Here's a video that describes how it works a bit https://www.youtube.com/watch?v=oJxWhmt5m-o