How to secure the update operation in this scenario - node.js

I have an app that recommends gifts to the user, after they answer a couple of questions. In the case that the user likes or dislikes a gift, I need to send an update request to the db to update it's 'liked' field. Users are not required to sign in order to like/dislike questions. The app is built using Angular and used Express at the backend to do the CRUD operations.
My question was, is there any way this operation can be done in a secure way, so that the user can not open the dev tools and get the info which would enable them to send repeated requests or anything like that? Is there anything I can change in the Express code? Or would I need to change the security rules?

Express should have a way to identify duplicate request. User id or some kind of token should be with request. But I see that sign-in of user not required in this case.
You can generate a temporary token every time some gifts are shown to user. This token should be generated and saved temporarily on express and you can send it with gifts data. So now when your frontend send request for like/dislike, this token will be in request.
So now express will do following steps
Checking if temp token is valid (it can match it with saved tokens)
If valid then it will update the database (like/dislike)
After successfully update it will remove that temp token.
So now, even if user send duplicate request it will be rejected by express as temp token will be not valid.
I hope it will solve your problem.

Related

Clean Architecture: how to properly authenticate users

I am making a project using Express and Nodejs.
I am learning how to implement learning how to implement clean Architecture properly.
I've made so far a Entity whose is a Balance (income/outcome).
But, in order for a particular user to be able to insert a new Balance, it's needed to be logged in.
So, in the Controller, I am receiving a Request which has a body with the income data and headers with the authorization token.
This controller makes the validations and forward the body as a DTO to the CreateBalanceUseCase.
My problem is that when i reach the CreateBalanceUseCase, I should call the data-access in order to save the data on the Database. But, the authorization token should be validated calling the AuthorizationDataAcess in order to find a user with same authorization token. But doing so, I violate the Clean Architecture I guess, right? Because I am trying to access the data-acces of the Authorization(aka User) inside the BalanceUseCase.
Also, on my database, I have a 1-n relation of the UserId with the Balance. So I can know what balance belongs to what user. So, also in order to save a Balance, I need to get the userId.
My second approach was create a Express Middleware that authorize the client and returns a userId, so whatever I must do through the app that needs authorization, It must use this middleware.
The problem is that I must access the data-access layer on the presentation layer
Whats the best practice in this situation? Or am I getting the Clean Code Architecture all wrong?
If there is any code or something else I could do to clarify more my question, feel free to comment it out.
Best regards.

Keep temporary data until send response - Nodejs

I'm working on express server application and there are bunch of api endpoints that I configured. Almost all create and update requests, I need to store requested user's userId in order to keep log. I created a middleware function that verify user JWT access token and retrieve userId from access token payload. In my current situation, I add user info as req.body.loggedUser in req body. I think this is not a good thing to do. I do it like,
req.body.loggedUser = accessTokenPayload.user[0];
This works fine in every POST request. But I need to do it in right way. And also this method cannot use in GET requests. If nodejs can keep temporary variable until a request done its process I can keep log on GET requests also. So all I need to do is keep user info as temporary data until request process done. How I can do it.
Just add it to the req variable:
req.loggedUser = accessTokenPayload.user[0]
This works in GET requests as well

firebase_admin auth.verify_id_token is very slow

I am resolving user data using firebase for auth like so:
from firebase_admin import auth
decoded_token = auth.verify_id_token(client_id_token)
I am initializing my firebase creds with firebase_admin.initialize_app(cred)
Here cliend_id_token is a token that the client sends. However, this takes around 1 second to perform, which seems way too long. One possibility is to use a caching layer above this (lru cache, memcache) but it still seems that it should not fundamentally take so long. Looking at the the signature of verify_id_token there does not seem to be anything that stands out as something that I can pass in:
def verify_id_token(id_token, app=None):
Any thoughts on how to diagnose (or if I am missing something)?
The problem is because that function does an http request in order to have the key to decode the jwt. In addition, because it returns info such as the email of the user, while the jwt contains only the uid as sub field of the decoded jwt, I think that it does another http request under the hood to get the user from the decoded uid.
You should implement your custom decode function, following the docs: https://firebase.google.com/docs/auth/admin/verify-id-tokens
I'm having the same issue. It's about 200ms for me (I'm using fastapi). #EuberDeveloper - glad to hear it's the same on node js - you saved me from testing it out.
I wanted to mention how I got my setup working faster in case anyone would benefit.
I've got Google API gateway with Firebase security defined in the swagger spec in front of a Cloud Run instance. API gateway validates the jwt (as per the swagger spec) and passes on the authorization header to the backend as a renamed header (from memory it's X-FORWARDED-AUTHORIZATION but best to double check). This is pretty fast.
Then in the backend you don't need to validate the id token since it'll already be validated by the time the request gets there. And if you send the UID along in the request to your backend as well as the idtoken in the authorization header, you can fetch users with the UID field you send. This removed that 200ms it was costing me to decode the id token.
Note - if you want to do things like check how old a refresh token is and revoke it for some reason then you'll still need to decode the id token.

Best way to handle authentication on a react-redux single page appliction?

I'm currently sending the client an empty html document with a few scripts included that set up my single page application with react-redux. After everything is set up I'm fetching the dynamic data using AJAX and determine if the user is logged in or not. If the user is not logged in, he will see the products available only for users that are not authenticated and conversely.
Even though I am a noob, this seems extremly primitive to me and I don't know how I can do this better.
So what is the best way to handle authentication in react-redux applications?
Thanks a lot for helping.
There's a few options:
Passport which you can install through npm and it has a variety of strategies you can authenticate through such as Auth0 Link here
Firebase - a solution that google has that can be used as a drop-in authentication module. Link here
Meteor framework - I believe this framework has multi user authentication. Link here
First, for authentification you need to have a token or session id on the client side. So, there should be next steps:
After login, you receive token|session_id from backend and put it to the store and also to the localstorage not to lose it after page reload.
While initializing your app, get the token from localstorage and put it to the store every time.
When you do request for products list, add the token to ajax request (usually in headers).
Based on token, back-end application should returns another list of products.
It is a regular logic for such situations and of course it requires work on back-end side as well.

XSS Protection in Express Apps

I am developing an express app which serves as a REST api with web client and may be future mobile clients. I am using a Oauth 2.0 token authentication for both clients. This gives a good deal of security against CSRF. I want to know How to provide security against XSS.
*I made the tokens validity period very less, requiring the client to request with refresh_tokens and other client details for access_tokens. This makes it a bit safe but not entirely*.
I am concerned with the with client_id and client_secret being stolen since its present in the front-end javascript code and it being used by other client to validate. I am thinking of using a JWT for the client authentication, will this be helpful?
Data Sanitisation is another which I am confused about. There are modules like validator, express-validator which give regex validation. According to this blog post JSON Schema validations are fast. In the REST Api JSON will used for data exchange so I was wandering why can't I use modules like tv4 or any other JSON Schema validators for data validations?? I am not asking for suggestions to use what, I just want to know the basic difference in the kind of validations each provide and specially from a point of view of XSS protection and sanitisation.
So you have three separate questions here:
1) How to protect against XSS: As long as you use JSON to share data between the client & server and use standard libraries/methods for encoding/decoding JSON, you are mostly protected. After this, you only need to worry about DOM Based XSS, which is harder to be protected. But basically you need to be careful for not using any user supplied input that can be interpreted as anything other than "string" you intended. (please visit https://www.owasp.org/index.php/DOM_Based_XSS for more information)
2) client_id and client_secret being stolen: This does not seem to be possible in the way you require. In your scenario (where you distribute clientid&secret in javascript code) there is no way on server side to know whether the request is coming from your client or a fake one.
3) Data Sanitisation: I see two levels of sanitisation in the libraries you & blogpost mentioned. validator or express-validator is mostly used to validate individual data fields. Whereas others can validate a JSON object structure in addition to what "validator" does. If you require all exchanged data is in JSON format (as suggested for XSS protection as well) then you can use json object validators like tv4. (the only drawback of tv4 seems to be allowing latest json spec, which should not be a problem for you)
BTW: It would be easier if you specified your client application is purely client-side javascript (angularjs). I could not understand your question until I found this info in comments.
I have developed Restful Authentication System same as your case with NodeJS, MongoDB, ExpressJS in order to provide flexible authentication system for multiple clients like web, mobile. Let me summarize you the important points.
I have used html5 localstorage to keep user token after first time login by using login form. When user click login button, username and password sent to server and validated. After successfull validation, unique access token sent to client and stroed in local sotrage. If you have vulnerability on your client application, anyone can get your access token and make request by using your token. In order to prevent this, you need to use ssl connection for your app. This problem does not exists only restful auth systems, this can be happen in server side session storage. Let me explain this. I am using PHP for session. When user logs in, user session saved in to temp file on server and that session id sent to client browser. Somehow, if I can get that id, I can make request with header that contains someone's session id. When you compare, restful auth seems more flexible to me. I suggest you to ;
Use SSL connection prevent your access_token from to be stolen
Generate access token with powerfull encryption methods(SHA-256)
Small expire time for access_token the better
Implement a middleware for token validation for backend service usage. I mean make your requests like;
/use/update/{userid}
with custom headers contains your user token.
Design 5 attempt failed system for your backend. If user cannot success at 5 time try, this means someone tries to send random tokens in order to get in to system. Detect and block that IP
You can also deny requests other than browser clients.
Those are the informations that I have learnt while implementing the project.

Resources