I would like to set up a mechanism to track every user http session based using a Cookie object. Therefore I store the user ID in a Cookie which I will communicate then to the client in the response body (once the login process is successful) such as :
Cookie loginCookie = new Cookie("userId", userId);
httpServletResponse.addCookie(loginCookie);
I have a got three questions please :
1) How to retrieve a given user http session based on his Cookie ? Shall I store the JSESSIONID instead of the userId for this purpose?
2) Encrypting the user cookie won't prevent the cookie from being compromised by some attacker eavesdroping the communication between the client and the server. Thus the attacker could reuse the cookie to request the server as being the actual user since the same cookie is being communicated each time the user requests the server. I don't really see where encrypting the cookie could help. Shall I use a digital signature algorithm as well in order to authenticate the sender?
You should store the session ID in the cookie, and the user ID in the server-side session.
Cookie re-use should not be an issue if you are using https, which mitigates the risk of eavsdropping. If you are not using https, no manner of encryption will help you.
Related
I am Looking at the Network activity of this page: https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
Specifically at the post request with the Name: "search". Its using an authorization token.
tldr: How is the following authorization token stored on the Client side?
Goal:
I would like to understand how the browser (client-side) stores this authorization token. I dont Need to get the data or know how to scrape with selenium or sthg. I would just be interested in the mechanics behind.
What i tried:
I find the token in the page source: view-source:https://helm.csod.com/ux/ats/careersite/4/home?c=helm&lang=de-DE.
It seems like there is an object csod created in /player-career-site/1.15.4/pages/home.js.
then the key is stored in csod.context.
Finally, csod.player.initialize(csod.context) is called.
Unfortunately, i failed digging in the Code and finding These function as there where too many Matches for initialize and my js are skills too bad.
As storage i am only Aware of the Cookies. It might be transformed / encrypted and stored in the cookies? But how is it then restored to the "original" token, before being added to the request Header?
This seems to be a CSRF prevent method.
The token is created with a key in the back end, it stores the original key in a session and sends the token to the client side.
When the client sends a request, the token is posted with the data as a header or with the data, then the back end gets the stored key in the session, generate the token with the same method and compare it with the posted token. If they are equal there is no problem, access granted.
It is not necessary to restore as you can't decrypt that depending on the algorithm (sha256, md5, etc)
And the browser don't do that, as it can be manipulated, there is no sense to.
The token sent here is JWT(JSON Web Token). This is a widely used standard authentication mechanism.
You can create your own token in any languages like JS, Java, PHP, Python, etc.
I am adding a basic authentication flow:
Let's say a user comes on a form. Enter his email & password.
Now an HTTP request is being sent to the server with credentials. The backend server checks the details and if successful, then returns a response containing the authentication token.
Most of the time this token is stored in localstorage and sometimes in cookies.
Now for every request the token is picked from the stored location and sent in the header.
On the backend, it is checked if the request header has the details or not. And then respond accordingly.
At last, whenever someone logs out then that token is removed from the front end.
I hope it helps! Let me know if you have any queries
This is a general question regarding web session management.
What is the best practice approach to managing session timeout?
Assume a system where a user logs in, a session is created on the server, and a token identifier is sent back to the client (via httpOnly cookie).
If the user attempts some access-based check where the session is validated, presumably it makes sense to update an expiry time on the session in the DB. Does this also mean that when this happens, we should update the expiry time on the session token cookie to match?
This seems like the most obvious solution to me, but constantly rewriting the cookie seems like a lot of overhead.
Any insight into best-practice approaches is greatly appreciated. Thanks!
How to manage session timeout to keep user logged-in, prevent he/she from accidental logout?
To keep user logged-in, it is not necessary to constantly rewrite the cookie. All you need to do is making the session token cookie's expires as Session, then as long as browser is open (client keeps using your site), the session token cookie is valid. Server does not need to know the session expires time (as there is no pre-defined session expires time any more), not mention store it in DB. After user close the browser, the session token cookie is cleared, and session is terminated (invalidated).
Normally, there will be a "session timeout" setting in server, such as session-timeout in Struts2, which kills the session if client doesn’t make any request after some time.
How to make session "validate" even if user closes the browser? That is, how to implement the "remember me for 1 week" feature?
To implement this feature, a new token cookie is used (e.g. RememberMeToken). When user login successfully (possibly enable the "Remember me" checkbox on UI), server will generate a unique random token and store it in DB (together with its expires time for security reason), make it belong to user account. This RememberMeToken cookie's expires time is pretty long (1 week for example), and will be sent back to browser together with login response.
When user close the browser and re-visit the site later (or the user is inactive for long time and the session is killed in server side), server checks session token cookie and find it's missing/invalid. At this point, RememberMeToken will be checked and compared with token stored in DB, if there is a match, server will make auto-login operation for corresponding user, and return generated session token cookie to browser. This all happens in backend, client user won't feel anything.
After 1 week since user enable the "Remember me" checkbox on UI and login, the RememberMeToken cookie is expired, and user need to login again if he/she opens browser and visit the site.
I think that internal mechanism of authenticaton should set a cookie with a token and store the same token on a server and next on every request compare the tokens from the cookie and on the server and if they are equal then user is logged in. I don't know where a server stores token, maybe in Session or something else (not persistent), but I'm sure that after the server's restart the server's tokens's store should be cleaned up therefore a user with an old cookie can't be authenticated. But in a practice after I restart my server a user is still authenticated and have access to pages because User.Identity.IsAuthenticated returns true. It seems to me wrong. Even if I remove this user from my DB (I use Membership) because I don't want this user have access anymore and restart my server, the user is still authenticated. Can anyone explain this?
Source of answer
Here is how authentication process works.
You setup some stuff in your web.config around where the login page is, how long the login is good for and whether or not to use sliding
expiration (should the time be extended if the user is active on your
site)
User comes to your site, enters their username and password.
That information is posted to your server. You take that information, verify that it is correct (authenticate). If it is
correct, the server then issues an encrypted cookie known as the
FormsAuthenticationTicket Note - this could have a different name in
the new Identity stuff, but the same principle.
The cookie's contents includes items such as the user name and expiration date of the login.
On each request, the server looks at the cookie collection for the authentication cookie. If found, it decrypts it, reads the values and
determines if this is still a valid cookie (expiration time). Once it
has the user information from the cookie, the server can use this
information to determine if the user is authorized for the resource
requested (look up by username).
If the cookie is not present, or has expired, or When the user logs out, the cookie is deleted from the cookie collection. Now, if the user tries to go to a resource that is for authorized users only, then the user is redirected back to the login page.
Hope this helps.
Can't we just store in the session if the user is logged in or not and get rid of the .ASPXAUTH?
ASP.Net_SessionId is a cookie which is used to identify the users session on the server. The session being an area on the server which can be used to store data in between http requests.
For example, the controller action may perform:
Session["FirstName"] = model.FirstName;
Then, in a subsequent action the first name can be retrieved from the session:
var firstName = Session["FirstName"];
The ASP.Net_SessionId identifies the session for that users request. A different user will submit a different cookie and thus Session["FirstName"] will hold a different value for that different user.
ASPXAUTH is a cookie to identify if the user is authenticated (that is, has their identity been verified). For example, a controller action may determine if the user has provided the correct login credentials and if so issue a authentication cookie using:
FormsAuthentication.SetAuthCookie(username, false);
Then later you can check if the user is authorised to perform an action by using the [Authorize] attribute which checks for the presence of the ASPXAUTH cookie.
So in summary, the cookies are there for 2 different purposes. One to determine the users session state and one to determine if the user is authenticated.
To complete the answer to your question, yes, you could get rid of the ASPXAUTH cookie and just use session to identify the user (I have seen this done in older classic asp applications) but I wouldn't recommend it. It is much better to have a cleaner separation of concerns and use the appropriate method where necessary. The session and authentication will have their own time-out values set. By using the session for authentication you will only have the single time-out. I'm not sure though if there are any security implications in just using session for authentication, but still I would keep them separate.
.NET issues an entirely different cookie, named ASP.NET_SessionId, to track session state.
The ASPXAUTH cookie is used to determine if a user is authenticated.
So these are 2 different concept i.e. Session State Management and Authentication Management using Form Authentication.
If you use Session to Authenticate and forget Form Authentication you will get rid of .ASPXAUTH
Both are required , using either resulting in the following vulnerability:
*ASP.NET_SessionId Alone: Session Fixation
*Forms Authentication Cookie Alone: Can’t Terminate Authentication Token on the Server
Also, you need to ensure they coupled together properly.Otherwise, the configuration also pose risk:
*Loosely Coupled ASP.NET_SessionID and Forms Authentication Cookies: Still Vulnerable
ref:
http://blog.securityps.com/2013/06/session-fixation-forms-authentication.html
Session state and authentication have nothing to do with each other. You can use one without the other.
I'm implementing my own OAuth authentication system (with refresh_token support) for an app and I have some questions about how to do it:
Client identification: The client is registered in the auth server and gets a client_id and a client_secret. How do I generate it? is there some kind of relation between both values?.
User authentication: The client sends the users_credentials (username+password for example) + client_id and gets a refresh_token and (temp?)access_token. That access_token is the one I should use in further request or I should use a accesss_token`=F(refresh_token,access_token,client_secret). In the second case what does the F function consist on?
Access token refresh: The client send client_id, refresh_token and gets a access_token (and a optional new refresh_token). Does the access_token need the same conversion (whatever it be), as in the point 2?
If I'm wrong, when and how is the client_secret used?
Complete answers and concrete examples will be "bountied".
The authorisation/authentication server generates these values when you create an account with them (for instance when you create a developer account with Facebook or Google). If you are doing these parts yourself, they should be cryptographically secure pseudo-random numbers or letters. Remember that the client ID is usually publically visible, so choose a reasonably large set of alpha-numerics (I use 30 characters). The secret is private and can be harder to guess so I chose 30 digits with letters, numbers and symbols. These are not related to each other, it is just that one is public and the other isn't.
The usual way this works is that there is a browser redirect to the auth server passing the client id in the URL (and redirect uri) and specifically NOT the user id and password. The whole point of OAuth2 is that the client system never sees the user name and password, only the auth server. After this redirect, the auth server verifies the client id, checks the username/password (for instance) and then returns to the redirect uri with a temporary code. This temporary code is passed back to the Auth server in order to obtain an access token. Since this call is made as a POST from the server, it also passes the client secret to verify that it really is the correct client system and not someone who stole the client id from somewhere else. At this point, the auth server will return an access token (and optional refresh token - you do not need to use them, I don't).
If the client system wants to log the user in without them having to type in their username and password all the time, it can use a refresh token, if available, to call back onto the Auth server and if the Auth server is happy that the refresh token is still valid and any other business rules are correct, it can give you back another access token directly without the user being involved.
I recommend reading the OAuth2 spec here: OAuth2 Spec RFC6749. It can take a while but if you delete the bits you don't need and reduce the amount of data, there are plenty of useful examples in it.
FIRSTLY, The client identifier can be any string that you want, but it should be unique for each client. It can even be the client's choice if you wish.
The client secret should be a cryptographically strong random string. Here is how you could generate one in C#:
RandomNumberGenerator cryptoRandomDataGenerator = new RNGCryptoServiceProvider();
byte[] buffer = new byte[length];
cryptoRandomDataGenerator.GetBytes(buffer);
string uniq = Convert.ToBase64String(buffer);
return uniq;
SECONDLY, The whole point of OAuth is to allow external apps to do things on your behalf without asking for your credentials. So, you need to implement an authentication server that does the logging in part for you. The user opens the app and gets an option to Log in using your website. You tend out access tokens and refresh tokens once the user has keyed in his credentials. The app can then simply use the tokens to perform actions on the user's behalf. I wrote an answer to How would an efficient OAuth2.0 server / provider work? that explains how access tokens can be constructed.
Remember, the need for refresh tokens and the lifetime of access tokens purely depends on how you intend to use them and what does your security framework look like.
LASTLY, The refresh token can also be an HMAC encoded string/a JSON object as I had explained in the answer to the linked question. You can have random refresh tokens and a large backend storage to keep it to verify the tokens in the incoming requests, or have HMAC encoded strings for added security/less storage requirements/latency to decrypt/encrypt tokens.
Also, do make sure that you go through all the flows and possibly the RFC too as mentioned by Lukos.