How does the user session work for OAuth2 authentication type Jhipster application? - jhipster

An Oauth2 client application generated by Jhipster has a behaviour issue after some idle time. After a signed-in user has some idle time on the application, interaction with the application will lead to an undesired behavior such as a data isn't fetched from the database.
I have learned that user session data is stored in a form of a cookie on the front end. For the Vue front-end, searching
this.$cookie.set(
yields no result.
I do see JSESSIONID in a request header after a user signs into the application. So, I assume that the session id also is stored somewhere on the server. For every REST request, the server would verify the session id in the request header by comparing it with the session id on the server. When the session is time out, the server no longer has the session id. Any REST request from the point will lead to undesired behaviour in the current implementation. A filter is needed to verify a REST request session id with the server.
I have a look at the code in the security package as well as the security configuration. But, I don't see any code dealing with a user session.
How does the server work in this regard?
Update:
To deal with an invalid user session for a sign-in, I notice that the ExceptionHandlerExceptionResolver will handle the InsufficientAuthenticationException after refreshing a browser. Otherwise, the exception won't be handled. How to resolve this issue?

Related

How can I secure my Node.js backend api data?

I may be a little confused about how backend servers work. Let's say I have a frontend React app with a login. The login information is stored in a database (i.e. MSSQL, MySQL, MongoDB) and I have a Node backend with routes for my app to fetch that information when a user is logging in or doing anything. When both my React app and server are hosted, I would make calls to the api and no confidential information (such as passwords) would be sent back to the client (just maybe a "success" message if the login information appears to be correct on the backend). My question is, what is stopping someone from finding the backend route and putting it into Insomnia to get the password or other sensitive information?
My first thought was to use express-session and auth on the backend to require a user to be logged in to an account to make such requests, but I think there are two issues with that:
How will that work when multiple users are logging in at once? Since the users are not technically physically visiting the api routes themselves, does session still know who is signing in to what account on the frontend? Will the second person logging in override the first person's session even though the first hasn't logged out yet?
If the auth doesn't kick in until a person is logged in, wouldn't someone be able to get the response password data from the login route itself?
Sorry if the question sounds dumb I'm just having a little trouble understanding the security aspect.
It sounds like there's a bit of a misunderstanding of how auth sessions work. There are two primary way sessions can work - either storing the sessions on the backend (older way), or storing session data in a cookie, typically a JWT (JSON Web Token). Cookies are bits of data that are passed from the server to the browser and anytime the browser makes a subsequent request to your server, it passes the cookie back too, so your server will always be able to get that data. The way this works for auth is the following:
A user signs into your application with credentials (username and password).
Your server validates the credentials by checking your database or wherever you're storing them and rejects the request if it fails. (Check out Auth0, Firebase Auth, or other auth services as doing this yourself can be a pain and open yourself up to potential vulnerabilities)
If the credentials are valid, the server generates a signed JWT token that includes data, like the username of the user.
The server responds with the body as well as a cookie containing the JWT, which the browser then stores.
The user requests some user-specific data from your server, and the browser sends the cookie with the JWT back to your server.
Your server validates that the JWT is valid by checking the signature. If it is valid, it uses the username from the token to get the user-specific data. If it is not valid, it rejects the request.
Because the signature occurs entirely on the server side (typically with some hashing algorithm and a secret key that you don't vend publicly), it would be nearly impossible for someone to spoof a JWT token signature. Therefor, your server is able to 1. trust that the JWT token is indeed valid if the signature is correct, and 2. find out what user is requesting data.
Here's a video that helps explain and visualize this: https://www.youtube.com/watch?v=soGRyl9ztjI
And here's a library for creating and validating JWTs in Node: https://www.npmjs.com/package/jsonwebtoken
Hopefully that answers your question!

How should I handle RESTful authentication while using JWT tokens?

I have read many articles and viewed many videos but there are a lot of contradictions. I try to avoid any external libraries and build the system from scratch, I have read about oAuth 2 but it is more confusing.
This is the flow that I think is ok untill now:
User fills a form using email and password and submits it.
Server verifies the password if it matches and responds back with a httponly cookie with a signed jwt token that expires in like 10
minutes. (I know I have to protect it against csrf attacks)
User gets logged in and every new request he is making to the server he will send the cookie in the header automatically and the
server will verify the token.
Everything is fine but I have encountered some issues and have some questions:
I want the user to stay logged in even after opening a new session so there is no need to login after the token expired or when he closes the browser.
What should happen if the access token expired?
There should be a refresh token attached to the user in database that gets added when the user logs in with an expiration of ex 7 days, then the server will respond with a cookie containing that refresh token?
On the new request while access token is expired,the user will send the refresh cookie to the server, if it matches the user database refresh token,server will respond with a separate cookie that will renew the access token?
If there is a refresh token where should you store it and what format? (cookie,database or where?)
Should I keep the user logged in based on this refresh token cookie?If is it httponly I can't read it and set the state that user is logged in. How should I do it?
I heard about that revoking the jwt token is problematic. How would you fix it?
How would you do this whole thing?Please explain the workflow, I try to avoid localstorage,as I read everywhere that is not safe for sensitive data.
I have implemented and deployed to production systems that do exactly the kinds of things that you are asking about here so I think that I am qualified to provide you with some guidance to solve your particular issues and answer your questions. The flow that you have listed above in the numbered list is definitely the correct path so far. I do understand your confusion going forward from there because there are many different options for how to approach this problem.
In addition to providing a login route that returns a new JWT to the client when the user submits a login form to the server, I would recommend also implementing a token refresh route that accepts a still valid JWT that was received from the initial login process and returns a new JWT with an updated expiration time. The logic for this new token refresh route should first verify that the provided JWT is still valid by matching it with a user in the database. Then, it should generate a new token using the same JWT generation logic as the login route logic. Then, the application should overwrite the access token data in the database for the user replacing the old access token with the newly generated access token. It is not necessary to keep an old access token in the database once it is no longer valid, which is why I suggest simply overwriting it with a new one. Once all of that is finished and successful, you can return the new JWT to the client and then the client should now use that new JWT when making any additional authenticated calls to the server to maintain an authenticated interaction with the server. This logic flow would keep the user logged in, because the client would have a valid JWT before calling the refresh logic and it would have a valid JWT after calling the refresh logic. The user should only be recognized as not logged in and not authenticated if they are no longer able to provide a valid access token that is associated with a user in the database.
As far as cookies go, whichever method that you use for maintaining the cookies on your client should be used for setting the refreshed access token as it is for setting the initial access token that you receive on login. If the server finds that an access token is no longer valid at some point in the future, if for example your client is not used after login until some time after the access token has expired, then the client should recognize a server response indicating that this is the case and present the user with the login flow on the client again so that a new access token can be acquired and stored in a cookie on the client.
I would not worry about revoking JWTs and instead just let them expire if they do and initiate a new login flow if it is found that a JWT has expired. Also, instead of using local storage I would suggest using session storage to store your JWT so that you have it for the duration of your user's session on the website and it is removed as soon as the browser has been closed. This will prevent the JWT from persisting beyond the session and should assuage your fears about saving sensitive data in the session storage. Also, when generating your JWT, you should also make a point of not storing any sensitive data in it because JWTs are easily reverse-engineered. This can also prevent any sort of sensitive data from being exposed on the client.
EDIT:
The key thing to remember when developing your server API is that you should have two different classes of endpoints. One set should be unauthenticated and one set should be authenticated.
The authenticated set of endpoints would not require an access token to be included in the request. An example of this class of endpoint would be your login endpoint, which does not require an access token because it actually generates an access token for you to use later on. Any other endpoint that does not expose sensitive or important information could be included in this class of endpoints.
The unauthenticated set of endpoints would require an access token to be included in the request, and if no access token or an invalid access token is detected the endpoint would respond with a 401 HTTP response code (indicating an unauthorized request). An example of this class of endpoint would be an endpoint that allows a user to update their personal information. Obviously, a user cannot update their own information if they cannot provide credentials to prove that they are the user whose information they are attempting to update. If the client receives a response with a 401 response code, that would be the signal that the client would need in order to tell the user to re-login so that a new valid access token can be retrieved. This possibility can be avoided on the client if the client is programmed to periodically check the expiration of the JWT that is currently being held on the client and initiate an access token refresh, but obviously you should still have logic in place to detect and respond to a 401 response code so that the client user flow is managed properly.

Using HTTPOnly Cookie in GET request (Retrieve user info from server using user_id cookie)

I'm following a tutorial where, after logging in a user, the backend sends a HTTPOnly cookie to the frontend containing the user id. However, HTTPOnly cookies are not accessible from the frontend (ex. document.cookie will not be able to read the cookie).
My question is, how is this cookie able to be used to retrieve user data? My thought process was that you would do something like GET 'server_address'/user/'id' where 'id' would be the user id stored in the cookie. But this obviously cannot work since the frontend can't access the cookie because it's HTTPOnly. A possible workaround I thought of was for the server to send the user id in the JSON response after logging in, but if this is the solution what is the point of even setting a cookie in the first place? That workaround makes it seem like there's no point in using cookies at all to save user sessions if you can just send the id back in the JSON response.
Please bear with me, this is my first time working with cookies. If it helps at all, I am using an Angular 4 frontend and a Node/Express backend
An httponly cookie is stored in the browser and is automatically resent back to the server with any future requests that match the origin of the cookie. So, the cookie can be used by the server to identify which client is making the request. If, for example, it was an authentication cookie that identifies who an authenticated user was, then the server would know which authenticated user this request is coming from and could use that information to authenticate the request and to know which user it was.
As you seem to already know, the httponly cookie cannot be retrieved by browser Javascript. That is the meaning of httponly.
how is this cookie able to be used to retrieve user data?
The cookie is sent to the server with any request from that client so the server can use the cookie to identify which user is making the request.
A possible workaround I thought of was for the server to send the user id in the JSON response after logging in
If the server wants the client to know the userID, then it should return it in the response. Or, it can stop using an httpOnly cookie so that the client can read the cookie. But, usually cookies that denote any sort of authenticated state are encrypted on the server so they often aren't intelligible to the client, even if they aren't httpOnly.
if this is the solution what is the point of even setting a cookie in the first place
Cookies are used for a variety of reasons. They allow the server to set some state that is associated with that particular client and each future request from that client will send that cookie back to the server so the server can have access to that info. The info could be authentication info, userID info, user preferences, etc...
That workaround makes it seem like there's no point in using cookies at all to save user sessions if you can just send the id back in the JSON response.
You don't really tell us much about your application, but cookies are often involved in implementing login and security and because they are automatically sent along with all future requests, they save the client the both of having to attach credentials to every single future request (because the cookie credential are automatically included). And, for requests such as a user clicking on a link in a page, the cookies are required because those types of links won't have credentials in them (and shouldn't).
My thought process was that you would do something like GET 'server_address'/user/'id'
So you plan to have any security associate with that request? If so, then you need an authentication scheme so that not just anyone can request info for any user. That's often what cookies are used for. You login, the server sets a credential into an encrypted cookie. That credential identifies a particular authenticated user so that for future requests from that same client, the server can use that cookie to see who the user is and whether they are authenticated.
We set cookie as httponly to prevent XSS, imagine if there is a security flaw that allow hacker the inject script <script>sendToHackerServer(document.cookie)...</script>, so user's cookie ( include session) will be sent to hacker server, then hacker can gain access to user data with that session. since these httponly cookie will be readable through http request only, session cookie will not be sent by injected script, and ur express backend can read these cookie with req.cookies.

C# MVC insufficient __RequestVerificationToken cookie regeneration

We are using C# MVC with Entity Framework and custom authentication implementing OWIN to make authentiation available by a custom user database.
Users login and authenticate themself by username and password by a standard login form.
To fit common security messurements OWIN regenerates the ".AspNet.ApplicationCookie" on each login and logout, I also force the "SessionIDManager" to regenerate a new Session ID (saved in .AspNet.ApplicationCookie) on each authentication change.
We use QUALYS to test the application for well known attack scenarios such as XSS, Session Hijacking etc. One imortant technic is to issue and validate Antiforgey Token which will be placed inside the form field AND inside a cookie stored on the client. As I unterstood these do not have to match since they are encrypted and get verified after decrypted on serverside on POST request (with ValidateAntiForgeryToken Attribute).
As mentioned above we use QUALYS to cover possible vulnerability scenarios. The report mentioned a security issue with the "__RequestVerifiationToken" which is set in the cookie and will not be regenerated until it gets invalidated by time. I reproduced this by tracking the traffic with Fiddler.
So the Token are there, get verified and I can log in, log out, chagne password and so on.
My question is, is there a build in possibility to reissue a __RequestVerifiationToken for the cookie?
When using the HtmlHelper #Html.AntiForgeryToken() it regerenates a new token for the hidden form field on each reload, but the cookie value keeps the same over time. I need to regerenate the cookie __RequestVerifiationToken value as well, at least on login / logout actions.
A side question is why internet explorer (Edge) requests result in a long time request when I manipulate the hidden form field content, firefox instead gets the error that a AntiForgery Erros occured?

in ASP.NET Web API, How to de-authorize a user immediately after account lock-out or delete?

I'm building a new Web API application using OWIN cookie authentication (ASP.NET Identity 2.2) for security.
I'm new to the whole cookies thing, but I've got a head-scratching problem: How is a logged-in user immediately blocked from using the API if their account has been deactivated (either deleted or locked-out)?
This arises after a startling discovery that if I have a user logged in on a client app, and I delete their user account via a different app, they are still able to access the API (i.e. the [Authorize] filter still succeeds because their cookie is still valid).
Somebody please correct me if I'm wrong, but AFAIK, cookies are not stored on the server, so there is no way to "invalidate" the cookie.
Yes, if the user logs out, they won't be able to log back in again. Also, I understand that setting an expiry on every cookie upon successful login will mitigate the problem.
But what about the following scenario: a system administrator (let's call him JoeAdmin) gets fired or otherwise becomes untrusted and some other administrator locks out his account. If JoeAdmin happened to be logged in when he got fired and became disgruntled, he still has access to the system and can do some real damage.
In this scenario, how could JoeAdmin be blocked immediately?
JoeAdmin happened to be logged in when he got fired and became disgruntled
Also JoeAdmin could have saved the cookie value offline, awaiting for his account to be revoked, and then later restores the cookie value to his browser.
OWIN cookie authentication is not ideal if you ever need to immediately invalidate logins.
This is because all the state information about the user is stored client-side, authenticated with a secret only on the server-side.
That said, you could do something with Oauth2 refresh tokens like here. e.g. have an access token that expires after say a minute, which when expired the application has to use a refresh token in order to gain an access token for another minute.
This way, any revoked accounts are only exposed for a short time. However, you may need to deal with the complexity of out-of-sync clocks on client and server.
Long story short, if you need to secure your system in this way, traditional server-side tokens would be the way to go. They are more secure in this regard.
The risks with using OWIN cookies are very similar to those of using JWT's for authentication. See this comment and the associated question and answer.

Resources