node-js server security, with react-native client - node.js

Im wondering if there is a way to only accept http requests from target react-native app.
What i mean is, currently, my nodejs server (using express) accepts connections from any means (even postman requests). Is there a way to make server only listen to desired app?

Use some level of security tokens. I use Passport-JWT with JSON Web Tokens that are generated after the user logs in.

TCP/IP is client agnostic so the server will always allow connections from anyone not on an IP based blacklist. However you can easily use tokens, keyword parameters or other means to block clients you don't like. The question is whether the connection needs to be secure, hence some kind of token exchange or you just want to prevent accidental damage. curl is very helpful if you want to test what a client an do with your server.

Related

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

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.

Is HTTPS behind reverse proxy needed?

I have an API server running behind an nginx reverse proxy. It is important to have all requests to my API server be secured via TLS since it handles sensitive data.
I've setup nginx to work with TLS (LetsEncrypt) so that seems to be okay. However, requests from nginx to my API server are still insecure http requests (this is all happening across docker containers, by the way).
Is it a best practice to also setup https between the reverse proxy and the API server? If so, how would I go about doing that without over-engineering it?
It all comes down to how secure or paranoid you'd like your implementation to be. It may also depend on the type of data you're playing with. For instance: I'd definitely do this for credit card numbers or other sensitive information.
As the comments have already stated, you would typically terminate SSL connections at the front facing webserver, assuming the API backend is also inside your LAN, which you trust and control. If you want to go that extra mile, you could also set up SSL on the API backend. Details of how to do that depend on the software you're using on your backend.
If you do decide to implement SSL on the API backend, the setup would be similar to what you did to setup Nginx with SSL on the frontend, with the main difference being you don't need to use a public certificate on the backend. It can be self-signed, since no one else besides your web server will be talking to it. Then it's just a matter of fixing all the URIs in your code to use HTTPS.

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

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.

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'.

Reverse proxy websockets (SSL), traffic through Stunnel to many node.js apps

I'm looking for some ideas...
I have a series of robust node.js apps that need to be delivered to specific users (post authentication), virtually no file serving, only the initial delivery of the index. The rest of the communication is all done via socket.io.
ClientA (login) needs to be connected to an application on lets say :90001
ClientB (login) on :90002
ClientC (login) on :90003
*All HTTP/1.1 ws need to be secure
I have tried a few configurations:
stunnel/varnish/nginx
stunnel/haproxy
stunnel/nginx
I was thinking a good approach would be to somehow use redis to store sessions and validate against a cookie, however that would most likely be done by (using node) exposing node.js on the frontend.
questions:
What are the risks in using node-http-proxy as the front piece?
Is this something that i should deem possible (to have one piece that "securely" redirects ws traffic and manages specific sessions to many independent/exclusive backends).
I am aware that nginx 1.3 (in dev) is to support ws, is this worth holding out for?
Has anyone had any thorough experience with yao's tcp_proxy module for nginx (reliability / scalability)?
I can't say I have done this before, but I can offer some ideas perhaps:
1 node authentication server which takes login details and sets a cookie specific to the server the user should connect to. It then redirects to the index page at which point, haproxy can direct the request based on the cookie. See this question https://serverfault.com/questions/75385/is-there-a-way-to-configure-haproxy-to-send-traffic-based-on-a-cookie
Alternatively, you could have the above authentication on all servers instead of just one. Haproxy would have to be configured to balance across all nodes if there is no relevant cookie header. Each node would do the set-cookie + redirect and subsequent requests should end up on the specific node instance.
bts, haproxy 1.5 dev now has built in support for SSL, so no need for stunnel anymore.

Resources