Angular 6+, Ability to securely create users from application - node.js

just a quick question because I am at a loss right now about the security logics behind creating users as an Admin in the application.
I mean, I have a form and I can add an username and a password for someone to connect as an user in the application, but how do I securely send the request to my server with the informations to add the users to the database
My backend and frontend servers are behind HTTPs. Are http POST requests inside the app secure?

Of course, the POST method is a safe request as long as you are using HTTPS protocol. HTTPS prevents Man in the Middle Attack and hence nobody would be able to tamper your information in transit to your web server.
As a side note, you should have a valid token like JWT, which would be authorize the sender of the information to create users for your application.

Related

How to create a secure user authentication flow for a webapp? (VueJS | NodeJS | ExpressJS)

Problem:
I want to create a webapp with VueJS and a custom backend with NodeJS (ExperssJS and PostgreSQL). It should be possible to login with a username and password. After a successful login, the user can access secured endpoints of the ExpressJS server.
Now I am thinking how I can securely authenticate HTTP requests after a successful login.
What I consider doing:
Using a JWT and providing it in the authentication header of every request.
When the user provides correct login data, the server creates a JWT and sends it as response to the client. The client stores the token and adds it to every HTTP request as the authorization header. Because the transport is secured with TLS (HTTPS) the token should not be visible while transporting. To provide a seamless user experience the token has to be saved at the client side, so the user does not have to authenticate for each request.
So my question is: How can I securely save a JWT token for further HTTP request authentication?
Possible options:
LocalSotrage - BAD IDEA! (not really secure)
Cookie - more security (but also not perfect)
Last thoughts:
Isn't there an "absolute secure" or a "best practice" method to handle authentication for such a scenario?
P.S. I am pretty new to this field, so please forgive me if i wrote something stupid :D I am also aware that there are a lot of tutorials on how to setup something like this, but what i want to know is, which technique is the best and most secure one.
Thanks in advance!
PassportJS also support using local strategy. You might want to take a look about it. here
If you are new then it's better to use already build user authentication flow like Google login, Discord Login etc.
There is a well known library called Passport JS which makes third party login system integration a breeze.

Securing NodeJS RESTful API and React client app

I've a backend RESTful API built in NodeJS and a front end application in React JS(NextJS), both hosted on AWS. The client and server communicates using JWT token.
I want to make sure both the client app and server side app are highly secured.
What i've done:
I'm using HTTPS for both client and server
Whitelist the client react app IP address so only the client react app can talk to the server app. This was done in AWS security group
Use cors in my server Node.JS application, to whitelist the client IP address again as an addition to No. 1
Use AWS WAF to secure the backend NodeJS application,
Use helmet in the NodeJS server backend API
Make sure the JWT token only last seven days, it'll be invalid and the user needs to login again to get a new token.
Answers i've looked at and used:
How to secure client app (react) and API communication
According to: RESTful Authentication i'm using Token in HTTP headers (e.g. OAuth 2.0 + JWT), this i sent for every client request
Using a refresh token: Refresh Token Jsonwebtoken
What i'm concerned about, and i need some help with:
1. Since the JWT token is how the server validates the client, is the JWT communication secured? Are there other steps i can take to improve the JWT security?
2. Is this application architecture secured enough?
3. Is there anything else i can do improve it's security, as i'm really concerned and want to make sure it's very secured.
4. Should i encrypt the JSON payload sent from the client to the server? because that's visible in any browser network tab under XHR, i'm sending username & password as payload for login.
I'm mostly concerned about security because i've integrated stripe payment in the application, and i'm also storing some sensitive data.
Any recommendation would be high appreciated, this is my first time deploying an production app.
As of what you have done the application must be pretty much secure.... except i would like to add a few things....
Make sure that the tokens have expiry and use refresh token to issue new tokens. The jwt stored at clients could be vulnerable for man in the middle attack. (For more performance use redis to store refresh tokens... look more on this)
If you are using https, the request will be only visible to the client's browser and not to any sniffers in the network (check on this whether ure able to see encrypted payload in sniffing tools like wireshark etc... to validate the https uve used). So its not necessary to go for any more encryption. That would decrease the performance of the api server.

jwt: Why is my token shown in Chrome DevTools?

I have a API in Express.js that will create blog posts and add them to my database. When I make a request from my React app inside of DevTools it will show my JWT. I am worried that when my site goes live people can see my token and make a request from their site to add unwanted posts. Please tell me what is going on and how I can prevent the security error.
When you send a request with a token in the header it will look like this in the header pane in Developer Tools:
I assume that's what you are wondering whether is safe or not.
The connection between the React app and the API is unencrypted when you are using ordinary HTTP. That makes a replay attack possible – an ISP or another server between the front-end and the API can read the token and pretend to be you later on with the read token.
The most important solution to that is to use HTTPS, which is encrypted HTTP. Potential attackers are unable to sniff and steal the tokens when you are using HTTPS. When you are dealing with usernames, passwords, etc., you should always use HTTPS.
HTTPS is free to use and not very hard to set up. See here for more details. There is also an interesting discussion here that you might want to read.
it's possible to see the JWT on the Chrome Dev tools because you are sending it as authorization header when creating a new blog post on your API, and you are making this request directly from the React application.
If the JWT is sensitive it should never be available on the front-end, you must have a server acting like a proxy, it should receive the request from the React application and then forward the request with JWT as the authorization header to your API.
Doing that you would avoid leaking the JWT, but it would still possible for someone to make requests to your proxy, which will be forwarded to your API.
If you want that only your react application be able to perform requests to your proxy, you could create a middleware which verifies the IP address of the incoming request (more details here), if it matches with your React app address then you accept the request, otherwise, you return a non-authorized error.
If you want only specific people to be able to create blog posts, then you should put authentication on the react application.

passport.js RESTful auth

How does one handle authentication (local and Facebook, for example) using passport.js, through a RESTful API instead of through a web interface?
Specific concerns are handling the passing of data from callbacks to a RESTful response (JSON) vs using a typical res.send({ data: req.data }), setting up an initial /login endpoint which redirects to Facebook (/login cannot be accessed via AJAX, because it is not a JSON response - it is a redirect to Facebook with a callback).
I've found https://github.com/halrobertson/test-restify-passport-facebook, but I'm having trouble understanding it.
Furthermore, how does passport.js store the auth credentials? The server (or is it service?) is backed by MongoDB, and I'd expect credentials (login & salted hash of pw) to be stored there, but I don't know if passport.js has this type of capability.
There are many questions asked here, and it seems that even though the questions are asked in the context of Node and passport.js the real questions are more about workflow than how to do this with a particular technology.
Let's use #Keith example setup, modified a bit for added security:
Web server at https://example.com serves a single page Javascript client app
RESTful web service at https://example.com/api provides server support to rich client app
Server implemented in Node and passport.js.
Server has a database (any kind) with a "users" table.
Username/password and Facebook Connect are offered as authentication options
Rich client makes REST requests into https://example.com/api
There may be other clients (phone apps, for example) that use the web service at https://example.com/api but do not know about the web server at https://example.com.
Note that I'm using secure HTTP. This is in my opinion a must for any service that is available in the open, since sensitive information like passwords and authorization tokens are passing between client and server.
Username/password authentication
Let's look at how plain old authentication works first.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form.
Many of the sections of this single page app haven't been populated with data due to the user not being logged in. All these sections have an event listener on a "login" event. All this is client side stuff, the server does not know of these events.
User enters his/her login and password and hits the submit button, which triggers a Javascript handler to record the username and password in client side variables. Then this handler triggers the "login" event. Again, this is all client side action, credentials were not sent to the server yet.
The listeners of the "login" event are invoked. Each of these now needs to send one or more requests to the RESTful API at https://example.com/api to obtain the user specific data to render on the page. Every single request they send to the web service will include the username and password, possibly in the form of HTTP Basic authentication, since the service being RESTful isn't allowed to maintain client state from one request to the next. Since the web service is on secure HTTP the password is safely encrypted during transit.
The web service at https://example.com/api receives a bunch of individual requests, each with authentication information. The username and password in each request is checked against the user database and if found correct the requested function executes and data is returned to the client in JSON format. If username and password do not match an error is sent to the client in the form of a 401 HTTP error code.
Instead of forcing clients to send username and password with every request you can have a "get_access_token" function in your RESTful service that takes the username and password and responds with a token, which is some sort of cryptographic hash that is unique and has some expiration date associated with it. These tokens are stored in the database with each user. Then the client sends the access token in subsequent requests. The access token will then be validated against the database instead of the username and password.
Non browser client applications like phone apps do the same as above, they ask user to enter his/her credentials, then send them (or an access token generated from them) with every request to the web service.
The important take away point from this example is that RESTful web services require authentication with every request.
An additional layer of security in this scenario would add client application authorization in addition to the user authentication. For example, if you have the web client, iOS and Android apps all using the web service you may want the server to know which of the three the client of a given request is, regardless of who the authenticated user is. This can enable your web service to restrict certain functions to specific clients. For this you could use API keys and secrets, see this answer for some ideas on that.
Facebook authentication
The workflow above does not work for Facebook connect because the login via Facebook has a third party, Facebook itself. The login procedure requires the user to be redirected to Facebook's website where credentials are entered outside of our control.
So let's see how things change:.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form that includes a "Login with Facebook" button.
The user clicks the "Login with Facebook" button, which is just a link that redirects to (for example) https://example.com/auth/facebook.
The https://example.com/auth/facebook route is handled by passport.js (see the documentation)
All the user sees is that the page changes and now they are in a Facebook hosted page where they need to login and authorize our web application. This is completely outside of our control.
The user logs in to Facebook and gives permission to our application, so Facebook now redirects back to the callback URL that we configured in the passport.js setup, which following the example in the documentation is https://example.com/auth/facebook/callback
The passport.js handler for the https://example.com/auth/facebook/callback route will invoke the callback function that receives the Facebook access token and some user information from Facebook, including the user's email address.
With the email we can locate the user in our database and store the Facebook access token with it.
The last thing you do in the Facebook callback is to redirect back to the rich client application, but this time we need to pass the username and the access token to the client so that it can use them. This can be done in a number of ways. For example, Javascript variables can be added to the page through a server-side template engine, or else a cookie can be returned with this information. (thanks to #RyanKimber for pointing out the security issues with passing this data in the URL, as I initially suggested).
So now we start the single page app one more time, but the client has the username and the access token.
The client application can trigger the "login" event immediately and let the different parts of the application request the information that they need from the web service.
All the requests sent to https://example.com/api will include the Facebook access token for authentication, or the application's own access token generated from Facebook's token via a "get_access_token" function in the REST API.
The non-browser apps have it a bit more difficult here, because OAuth requires a web browser for logging in. To login from a phone or desktop app you will need to start a browser to do the redirect to Facebook, and even worse, you need a way for the browser to pass the Facebook access token back to the application via some mechanism.
I hope this answers most of the questions. Of course you can replace Facebook with Twitter, Google, or any other OAuth based authentication service.
I'd be interested to know if someone has a simpler way to deal with this.
I greatly appreciate #Miguel's explanation with the complete flow in each cases, but I'd like to add some on the Facebook Authentication part.
Facebook provides a Javascript SDK which you can use to get the access token on client-end directly, which is then passed to the server and used to further pull all the user information from Facebook. So you don't need any re-directs basically.
Moreover, you can use the same API end-point for mobile applications as well. Just use the Android / iOS SDK for Facebook, obtain the Facebook access_token on the client end and pass it to the server.
Regarding the stateless nature as explained, when get_access_token is used to generate a token and passed to the client, this token is also stored on the server. So it's as good as a session token and I believe this makes it stateful ?
Just my 2 cents..
Here is an awesome article I found that can help you authenticate with:
Facebook
Twitter
Google
Local Auth
Easy Node Authentication: Setup and Local

Store username and password for API in cookie?

I've written a web application that interfaces to an API, in a different domain.
This API requests a username and password for certain calls (involving POST, e.g. to upload a photo to the API). For these calls the API uses https.
Is there a way I can store the username and password within the web app, so the user doesn't have to log in repeatedly each time they upload a photo?
Here's what I can think of:
The obvious way is to stick both in a cookie, but clearly that's a security hole, whether plaintext or hashed.
If it were a secure website, I could use a session ID: could I persuade the API owners to allow session IDs, or would that be impossible across domains?
Perhaps I simply have to ask the user to re-enter their username and password each time they make an API call.
Thanks!
If I understand your architecture correctly, your users are sending the API calls to a service running in a different domain. You are not a man-in-the-middle for this request, you are only providing the interface e.g. as a form-field in your web application. The user can send the API calls without you even knowing that he did.
In that case there is no way to implement this without storing some kind of authentication information in the browser (cookie, form-field, etc.) or have your users enter them for each request. They must come from somewhere and your server is not involved in the request.
What you can do is changing the architecture and start playing man-in-the-middle, like a proxy. Instead of just providing the interface, let the users send their requests to your web application instead of communicating with the service directly. Your web application adds the credentials and forwards the request to the service. The answer of the service will be sent to your web application, which can redirect it again to the user.
In this scenario your web application is responsible for authentication. Your web application adds the credentials to a request if the user sending the request was identified and has the required permissions. The credentials for the service are only passed from your web application to the service, they even can be kept hidden from the user himself.
Such a change has several implications of course. The load on your web application will increase and the logic will become more complex. Those trade offs must be considered.

Resources