0

I have created a ws websocket server in nodejs and a http server that is listening on a specific port and host is 127.0.0.1. WebSocket server connection is established on the upgrade event emitted by the http server. For security purpose I want the server to be accessible only on localhost/127.0.0.1 and not from 0.0.0.0 IP.

Example:

  1. ws://0.0.0.0:5050 - Should not accept connections
  2. ws://127.0.0.1:5050 - Should accept connections

How can I restrict the server to be only reachable from localhost and not from any other IP(including 0.0.0.0)?

const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });
server.listen(5050, '127.0.0.1');

server.on('upgrade', function (request, socket, head) {
  wss.handleUpgrade(request, socket, head, function (ws) {
  //conditional checks
  wss.emit('connection', ws, request);
  })
})

Can somebody please direct me to the proper way of doing this.

Jaspreet Chhabra
  • 377
  • 3
  • 14
  • Does this answer your question? [Restrict access to Node.js-based HTTP server by IP address](https://stackoverflow.com/questions/12349251/restrict-access-to-node-js-based-http-server-by-ip-address) – Artem Arkhipov Sep 01 '22 at 11:59
  • Simple solution would be add a check using request that is being sent,in which you can check the IP address in express it can be done using "req.ip" – Swarup Chavan Sep 01 '22 at 12:05
  • @ArtemArkhipov I tried the solution mentioned but none of them seem to work for me. Actually I am creating a ws websocket server which is using the http server in the noServer mode. May be this is the reason. Ref https://github.com/websockets/ws#external-https-server – Jaspreet Chhabra Sep 01 '22 at 12:14
  • @SwarupChavan I am not using express. – Jaspreet Chhabra Sep 01 '22 at 12:20
  • Even if its not express, you still get a `request` which will probably contain the IP address you can filter on? (Express is just a small wrapper for some functionality anyway) – somethinghere Sep 01 '22 at 12:23
  • can you try with request.socket.remoteAddress – Swarup Chavan Sep 01 '22 at 12:25
  • @SwarupChavan Even if I make a request from 0.0.0.0, request.socket.remoteAddress returns me 127.0.0.1. I am checking this in upgrade event. – Jaspreet Chhabra Sep 01 '22 at 12:31

3 Answers3

0
if(req.socket.remoteAddress !== '127.0.0.1'){
res.send('403 Access Denied');
res.end();
} else { 
// allow access
}
Raghava
  • 1
  • 1
  • 2
    Could you elaborate a bit, this looks promising but notice that the OP isn't using express and in his handlers does not have the usual `res` or necessarily normal `req` object. – somethinghere Sep 01 '22 at 12:24
  • Even if I make a request from 0.0.0.0, request.socket.remoteAddress returns me 127.0.0.1. I am checking this in upgrade event. – Jaspreet Chhabra Sep 01 '22 at 12:33
0

0.0.0.0 isn't an IP address. It is a non-routable meta-address used to designate an invalid, unknown or non-applicable target.

You might have a client that treats requests to 0.0.0.0 as being intended for localhost, but that isn't a security problem since your server still won't be accessible outside of the current machine.

Your existing code, where you only listen on 127.0.0.1 is sufficient.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Basically, the app I am developing is going to be installed in the client's machine. When a server binds to the address 0.0.0.0, it allows connections from every IP address on the local machine, effectively exposing the server to every possible network. When the server is listening on 0.0.0.0, an unauthenticated attacker may be able to connect and send messages to the socket server without the consent. This may lead to the disclosure of sensitive information. – Jaspreet Chhabra Sep 01 '22 at 12:37
  • @JaspreetChhabra — `server.listen(5050, '127.0.0.1');` — you **aren't** doing that though. (As I pointed out in the third paragraph of this answer). – Quentin Sep 01 '22 at 12:38
  • Right but when I am making a request using "ws://0.0.0.0:5050", it does accepts the connection. – Jaspreet Chhabra Sep 01 '22 at 12:40
  • @JaspreetChhabra — I refer you to the second paragraph of my answer. – Quentin Sep 01 '22 at 12:40
0

Access and security that you are talking about are supposed to be done at the firewall of your instance hosting nodejs server.

However, if you still want to implement it on your nodejs layer you can dig the request object there you will find the IP address from where the request is coming, and based on that you can take your action.

Hope it helps, Thank you