How do you secure information between 2 servers? - node.js

Forgive me I'm still very new to this.
I am building multiple front ends which all need to be able to speak to a single back end server api. These front ends are hosted on different domains so I ran into CORS issues and from what I've gathered my best solution is to send the appropriate data on the front end to a proxy server on the same domain which then forwards that request to my api server.
I'm concerned about the security of this action though and looking for the right way to secure the data being passed from the proxy server to the api server.
So my data goes:
client --> proxy --> api
and I want to know the best way to make sure the api knows the proxy is who it claims to be. Is my best bet just a simple password exchange? A json web token?

Yes, you can use JWT actually. The proxy server can send a JWT along with each request to the API server, and the API server can then validate the token to ensure that it was issued by a trusted source.
Here's a scenario how JWT authentication might work in this:
The client makes a request to the proxy server, including any data
that needs to be sent to the API server.
The proxy server generates a JWT, which includes a unique identifier
for the client and any other relevant information, and signs it with
a secret key.
The proxy server sends the request, along with the JWT, to the API
server.
The API server receives the request and extracts the JWT from the
header.
The API server validates the JWT by checking the signature against
the secret key and verifying that the JWT has not been tampered
with.
If the JWT is valid, the API server extracts the client identifier
and uses it to determine whether the request should be processed.
If the JWT is not valid, the API server returns an error response to
the proxy server.
Note:
It's important to keep the secret key used for signing the JWT secure, as it is the key to ensuring the authenticity of the JWT. It's also a good idea to regularly update the secret key to further enhance security.

Related

Security of getting access key from auth server

I have a question about the security of getting access key in auth server:
When the authorization server redirect to the client server with the authorization code in the query param of the url and then after the redirection the client will make a post to the authorization server with a secret key to get the access key. What if someone get the url with query param sent by auth server and copy pasted it to the browser, will the auth server give the access key?
I mean they have same route and it means it will go through the post api and use the secret key of that client to get the access key. How to prevent this scenario?
There are a couple of basic protections here that are sufficient for most use cases:
The connection between the client server and authorization server should use SSL so that the traffic cannot be intercepted
The infrastructure should be locked down so that attempts to intercept server to server traffic are not allowed
FINANCIAL GRADE
It is also possible to use stronger secrets between the client server and authorization server, such as an X509 client certificate. This ensures that if someone manages to intercept an HTTPS request they still cannot use the secret, because they do not have the private key.
OAuth is a framework so there are different ways in which it can be used. In some industry sectors, such as banking, it is required to implement higher strength profiles such as those specified in Financial-grade Client Requirements, which require this type of stronger secret.
PEOPLE RISKS
A rogue employee could potentially steal either type of secret. Bear in mind also though that the Authorization Code Flow requires valid user credentials in addition to the client secret.

NodeJS Authentication for Multiple RESTful API services

I would like to seek help from you guys.
I have multiple RESTful API services running in NodeJS Express. Each API is hosted by different NodeJS with different port. And in our front-end, it is accessible via reverse proxy.
We are now moving to a secured services. However, there's a problem in authenticating with the services. The front-end should request 1 auth token upon login that can be used in accessing the internal API services (API is also accessible in our public domain /api/).
How can we solve this problem?
Current Setup
You could issue a signed JWT token upon login (see https://jwt.io/).
The front end application has to send the token back with each API call.
Each API server has to know in advance the key (public key or symmetric key depending on the type of the signature algorithm) and use the key to check the signature of the token is valid.
If it is valid, the API server knows it can trust the token content, and decide whether to serve the request. The token would contain the identity of the user, expiration time, ...
Note that signing the token does not encrypt the data: if you need to convey sensitive data through the token, it needs to also be encrypted
Thus it is not necessary to establish a session and then share the session across the many API instances. Knowing the key is enough to trust the token content
To pass the JWT in API calls you can use a header:
Authorization : Bearer theBase64EncodedToken
Of course, it is up to you to check if this scheme satisfies the security concerns related to your application.

Is JWT necessary over HTTPS communication?

I'm developing a MEAN stack application, and I'm currently setting up an account system. I've seen several tutorials about Authentication, all using JWT.
I am wondering if, JWT could be used as way to secure communication transport over non-secured connection like HTTP?
I've set up HTTPS to communicate from my Angular 4 front-end to my NodeJS + Express back-end, and thus, wondering if JWT are necessary to secure my communications?
JWT should not be confused with encryption. From jwt.io:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a
compact and self-contained way for securely transmitting information
between parties as a JSON object.
The JWT is signed with public/private key pairs so the sender can be verified, and verified that the payload has not been modified. However, the JSON Web Token is in clear text.
var token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
var payload = token.split('.')[1];
console.log('Payload: '+atob(payload))
Below is a figure from jwt.io showing the authentication flow when using JWT.
You need SSL/HTTPS to encrypt the communication. Without SSL/HTTPS attackers can sniff the network traffic and obtain the JWT, hence your application is vulnerable to man in the middle attacks.
Is JWT necessary over HTTPS communication?
No. Communication protocol (HTTP v.s. HTTPS) is one thing, and authentication mechanism (JWT v.s. Session) is another -- these are 2 totally different area.
For communication protocol (HTTP v.s. HTTPS), HTTPS can be used alone, without any JWT tokens or sessions. For example, a static web site can be made (only HTML+CSS) and served with HTTPS. In this way, the web site can be certificated by CA and prevent forge attack.
Even if you need authentication in web application, JWT token is not the only choice. Session is old technology but it is still reliable, which made JWT definitely NOT necessary.
No, JWT is not required when your server supports HTTPS.
HTTPS protocol ensures that the request & response are encrypted on the both(client & server) the ends.
I believe you would want to send across user credentials in every request to the server, and in turn server validates the user before sending any response from the server.
Although you can do the above, but on the server-end, you would end up validating user credentials against a Database in every request which is a expensive task, you can avoid this when you use JWT.
JWT basically authenticates a user once & issues an access token which could be valid for a duration of time.
Nowadays developers prefer Token-Based Authentication instead of Session. Token-Based Authentication has lots of advantages over Session.
We use JWT i.e. JSON Web Token to generate a token after user authentication, every time your front-end app makes an API call so your system should check whether the request has a valid token or not if it is there and it is valid then it is considered as the valid user.
In short, we use JWT to validate our API calls it is nothing to do with HTTP or HTTPS
I'm new to JWT. Here is my scenario of an attack of JWT when it's in the http instead of https. Suppose a JWTa is issued to userA for accessing resource A on the server. A hacker is also a legal user of the server, he got JWTh to access resource H. Without the https protection, the hacker can sniffer the network and get the JWTa in the http header from A's request and put it into the hacker's request. Since JWTa is a valid token, so the hacker can access resource A. I guess the JWT protocol can prevent this, but I don't know how. After the signature is verified, the claim also needs to be verified. Seems the "aud" can prevent this, but I don't know how it works exactly.

Font End secure authentication only allowed to come from a specific website

I have a private rest API. Each of our clients websites currently performs server side authentication over SSL to start an order with us. Each client has a unique client id so I can identify which client is making the request and reject any client id which doesn't exist in our system. Is there a way to do this securely from the front end of a clients website with javascript? I can't put the client id in the client code since any developer could look at the source code and figure out how to spoof requests from another site. I think checking referrer headers is not reliable as well? Would really like to know the best practice for situations like this.
Not sure if I understand your question correctly, but typically you would encode your client id as a claim in the security token issued when authenticating your users. As the security token is signed by the issuer, you can verify that the token is not modified when you receive the token on each request.
Obviously you will need to use the https protocol to prevent the token from being stolen. See here for more information.

Is the client allowed to choose challenge (nonce) in Digest HTTP authentication?

Digest authentication looks like a flavor of challenge-response mechanism: theres's a random string which is mixed with the password (MD5 or something) by both the client and the server and only the result of such mixing is sent over the network.
Usually the challenge ("nonce") is chosen by the server and sent to the client. Wikipedia article on digest authentication lists a sample "session" - the challenge ("nonce") is chosen by the server there. I tested the same with IIS on my machine - again, the challenge is generated by IIS.
But in some posts like this one the challenge is generated by the client - the client just generates a random string and sends a request with the challenge and the product of the password and that challenge.
Is the latter allowed and widely accepted? Is the client allowed to choose the challenge ("nonce")?
In HTTP digest authentication, the server always generates the nonce.
However, HTTP authentication is extensible, and applications may implement other methods of authentication (beyond basic and digest). In the example you link to, the client is authenticating using WSSE, a form of authentication for (mainly SOAP-based) web services. In WSSE, the client generates the nonce.
The Digest Access Authentication scheme is only a one-way authentication where the client authenticates itself to the server but not vice versa. Only the server issues a challenge that the client needs to be responded to correctly to be authenticated. So only the server knows if the client is authentic but the client doesn’t know if the server is authentic.
Now the linked code does the exact opposite: The client issues a challenge to the server to authenticate it. So the client knows if the server is authentic.
The best would be to use mutual authentication.

Resources