Is a Socket.IO socket ID sensitive/private data? - node.js

When a new connection is handled by Socket.IO, it creates a Socket object, and one of this object's properties is id. This is an "unguessable" (according to the documentation) string used to identify the connection.
When building applications, is it considered safe, secure and good practice to broadcast this ID to other clients? My inclination is that hashing the ID and broadcasting the digest may be a better idea.

The id is not sensitive data unless your own code somehow makes it sensitive. There are no socket.io client operations that take the socket id, so if a client has a socket id, there is nothing they can do with it unless your code implements message that operate on it.
It is unguessable so that you can use it as an id to share with other clients while not allowing that client to know who's id they might have been given (like an anonymous id).
So, using it as an identifier to refer to some other user's socket is exactly what it was intended for and does not cause a security or privacy issue unless your own client operations cause such.

Related

How to persist HTTP response in redis

I am creating a long-polling chat application on nodeJS without using Socket.io and scaling it using clusters.
I have to find a way to store all the long-polled HTTP requests and response objects in such a way that it is available across all node clusters(so that when a message is received for a long-polled request, I can get that request and respond to it)
I have tried using redis, however, when I stringify http request and response objects, I get "Cannot Stringify Cyclic Structure" Error.
Maybe I am approaching it in a wrong way. In that case, how do we generally implement lon-polling across different clusters?
What you're asking seems to be a bit confused.
In a long-polling situation, a client makes an http request that is routed to a specific HTTP server. If no data to satisfy that request is immediately available, the request is then kept alive for some extended period of time and either it will eventually timeout and the client will then issue another long polling request or some data will become available and a response will be returned to the request.
As such, you do not make this work in clusters by trying to centrally save request and response objects. Those belong to a specific TCP connection between a specific server and a specific client. You can't save them and use them elsewhere and it also isn't something that helps any of this work with clustering either.
What I would think the clustering problem you have here is that when some data does become available for a specific client, you need to know which server that client has a long polling request that is currently live so you can instruct that specific server to return the data from that request.
The usual way that you do this is you have some sort of userID that represents each client. When any client connects in with a long polling request, that connection is cluster distributed to one of your servers. That server that gets the request, then writes to a central database (often redis) that this userID userA is now connected to server12. Then, when some data becomes available for userA, any agent can lookup that user in the redis store and see that the user is currently connected to server12. So, they can instruct server12 to send the data to userA using the current long polling connection for userA.
This is just one strategy for dealing with clustering - there are many others such as sticky load balancing, algorithmic distribution, broadcast distribution, etc... You can see an answer that describes some of the various schemes here.
If you are sure you want to store all the request and responses, have a look at this question.
Serializing Cyclic objects
you can also try cycle.js
However, I think you would only be interested in serializing few elements from request/response. An easier (probably better too) approach would be to just copy the required key/value pairs from request/response object in to a separate object and store them.

Can you rely on socket.id as a UID

Excuse my ignorance, day 2 of node.js/socket.io
I'm looking for a way to uniquely identify users for use in a database queuing system. I read a lot about using Express's session cookie, however I've noticed socket.id seems to be an UID that socket.io is already using.
Therefore I have been using socket.id to identify my users both in the database, and in creating private "rooms" to communicate with just them.
Is this a terrible idea?
A socket ID is just that - it uniquely identifies a socket. It doesn't uniquely identify a user, and it's definitely not intended to be used for that purpose. A single user (in many applications) might have multiple connections (and therefore multiple sockets with different ID's). Also, every time they connect they will be assigned a new ID.
So you obviously shouldn't use a socket.id as a user ID. Mustafa points out that you could reassign socket.id to a user ID, but I tend to think that's a very bad idea for two reasons:
socket.id is supposed to uniquely identify a socket, so you would run into problems when a single user has multiple sockets open.
Socket.IO, uses that ID internally a lot for storing things in hashtables, and if you change the ID, you might get unexpected results and hard to track down bugs. I haven't tested it, but looking at the Socket.IO source, that's what I would expect.
Better to generate ID's using another method then associate a user with a socket (for example, during the handshake using data from the cookie).
socket.set(key, value, callback) is the method explicitly intended to be used for associating your own data (like a user ID) with a socket connection, and is the only one guaranteed to be safe.
When the socket.io sockets are created, you can add variables as you wish to socket object. socket.userid = getUserID() will work fine. It is better to make assinging UIDs in database, and add them to socket objects when their authentication is succesful.

How to implement session using nodeJS TCP server with MongoDB?

I am creating a TCP based game server for iOS, it involves registration and login.
Users will be stored as a collection in MongoDB.
when login is done, I generate a unique session id - How ?
I wanted to know what all data remains with node server and what can be stored in db.
data like session tokens, or collection of sockets if I am maintaining a persistent connection etc.
Node.JS does not have any sessions by default. In fact, there is a plug-in for managing sessions with MongoDB.
It's not clear that you really need sessions however. If you're opening a direct socket with socket.io, that is a defacto session.
Node.js itself does not manage sessions for you. It simply exposes an API to underlying unix facilities for Socket communication. HTTP in it self is a stateless protocol and does not have sessions either. SSH on the other hand is a stateful protocol, but I do not think either one would be good for you.
Creating a uniuqe ID is really simple, all you need to do is hash some data about the user. Their SHA(IP address + time + username). See: http://nodejs.org/api/crypto.html
One approach a lot of applications take is to create their own protocol and send messages using that. You will have to handle a lot of cases with that. And I myself have never dealt with mobile where you have serious connectivity challenges and caching requirements that are not a big problem on desktops.
To solve these problem, founder of Scribd started a company called Parse which should make it much easier for your to do things. Have a look at their website: https://parse.com/.
If you want to do some authentication however, have a look at Everyauth, it provides a lot of that for you. You can find it here: https://github.com/bnoguchi/everyauth/.

Socket connection on iPhone (IOS 4.x)

I am working on a Chatting application (needs to connect to a server) on iPhone. The sending packet from iPhone shouldn't be a problem.
But I would like to know whether it is possible for iPhone to establish a incoming socket connection to server continuously or forever under mobile environment.
OR What do I need to do to give the connection alive ? Need to send something over it to keep it alive ?
Thanks.
Not sure why you want to have chatting app to have persisted connection... I'd better use SMS like model. Anyways, Cocoa NSStream is based on NSSocket and allows a lot of functionality. Take a look at it.
Response to the question. Here is in a nutshell, what I would do:
Get an authentication token from the server.
this will also take care of user presence if necessary but now we are talking about the state; once presence is known, the server may send out notifications to clients that are active and have a user on their contact list.
Get user's contact list and contact presence state.
When a message send, handle it according to addressee state, i.e. if online, communicate back to the other user, if offline, queue for later delivery or reject.
Once token expires, reject communication with appropriate error and make the client to request a new token.
Communication from server to client, can be based on pull or push model. In first case, client periodically makes a request and fetches all messages. This may sound not good but in reality, how often users compose and send messages? Several times a minute? That's not too much. So fetching may happen every 5-10 seconds.
For push model, client must be able to listen and accept connections.
Finally, check out SIP, session initiation protocol. No need to use full version of it though. Just basic stuff.
This is very rough and perhaps simplified. I don't know the target complexity of your chatting system. For example, the simplest thing can also be that server just enables client to client communication by distributing their end points and clients take care of everything themselves.
Good luck!
Super out of date response, but maybe it will help the next person.
I would use xmppframework and a jabber server.

Need ideas for securing a JMS based server process and database

I have a tool that is distributed freely as an Eclipse plugin, which means that I can't track who uses it or ask them to register.
Every client tool communicate via a JMS broker with a single shared server process (written in Java) and can receive messages in reply. The server connects via Hibernate to a MySQL database.
At present, the only message that the tool sends is a request for data, and the server gets the message and sends a bulk of XML data representing elements to the client, which displays corresponding items in the IDE. Hence, I don't think that there is much that can be done to the server except a DoS attack.
Now, however, I want to add the following functionality: a user can assign a rating to a particular element (identified by a numeric id), and a message will be sent to the server which will store the rating as an event in a rating event table. When next requests for data come in, the average rating for each item will be sent with the request.
My problem is that I've never deployed a tool that used a public server like this, even if it is hidden by the JMS broker. What attacks could be deployed against me and how can I defend against them?
There's the problem of DoS, and I'm not sure how to address it.
There's the possibility of injection, but all my data is numeric and I don't know how hibernate deals with things.
There's the problem of spam or dummy-voting, and I can't really think of how to address that.
I'm sure there are others...
With regard to the dummy voting, this is not secure (i.e. it wouldn't be acceptable for electoral purposes!) but it is a simple mechanism:
Create a GUID on the server, store it in an appropriate table and send to client. When client votes, it sends back the GUID, which is compared to the Database. If the GUID is valid, accept the vote and remove the DB stored GUID.

Resources