Generate unique sessionId with Express Cookie-Session - node.js

I'm using node/express.js with cookie-session in my application.
Currently, when a user logs in a cookie is stored in their browser with a value, for example: session: ABC123. If the user logs out, the cookie is deleted. When the user logs back in, the same cookie and value are stored in the browser session: ABC123.
I am getting the same session user_sid whenever i login.
i want to randomize the session user_sid every time the user logs in.

There is no notion of a session id with the cookie-session package.
In the typical scenario where the session data is stored on the server, a session id is generated that maps to a given user session data. This is this session id that is kept in the session cookie.
With the cookie-session package however, the session data itself is stored in the cookie - as opposed to on the server -, so there is no need for such a mapping or a session id at all. So in effect and unless the session data is actually updated from one session to another, the session cookie will be the same.

You want to call session.regenerate() when the user successfully login, that will do what you want and also address session fixation attack

Related

Is there a way to reuse session in express-session?

Say I have a login system and at first login, I store the session Id. now when the user login again can I retrieve the session Id, session.destroy() the new session and tell express session to assign the session data from the session store with this retrieved Id to this request?
Thanks
I'm using connect-sqlite3 as session store

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.

Is this a secure way to handle cookies?

The scenario is a web app running with no ability to store information locally, such as sessions. So in order to provide state, here's what I'm thinking. The server has a list of users and SHA256(passwords + salt). When a user logs in, I would set a name cookie with the username and a key cookie with SHA256(SHA256(password + salt) . ip).
This would allow the server to compare the credentials without knowing the plain text password, it wouldn't expose the password in the client's cookie, and would safeguard the logged in credentials against being ex-filtrated into an attacker's system since it would only work on that one IP address.
The only drawback I can see is that there would be no way to enforce expiry. So it would basically be a lifetime cookie for that user/password/IP combination, or at least until the web app erases the cookie or the user changes his password.
you must not use password anywhere in cookie even if it is encrypted.
give every user an id and on every login you must:
1. Update login Time
2. Create unique session Id
3. set cookie with unique session id
now on every request to server
1. validate session cookie
2. Check login time and current server time.
it is just basic structure..

A different way to manage sessions

I'm working in a cookie-less way to manage sessions in my project (expressjs), keeping all session data server side and using a token at client side (previously generated by the server) to validate the session on every request.
A new token will be created on user login and kept hide somewhere in the page, then, on every request this token will be written to the request header and validated server side. at this point server will search for the token in a session store, lets say redis, and get the session data if the token is found or respond with a message of session expired otherwise.
There are some things i'm considering for this:
Redis keys are created on user login with a settled expiration.
Every time session data is found in redis i have to 'touch' the key
so expiration time gets postponed.
Token will be validated along side with the ip address of the client so can't be used by other person.
My question is if this is can be considered a secure way to work with, and if there is anything i'm missing here. Thanks
OK, cookies are required for storing session. Express does it the ideal way.
In express session(not cookiesession) it is completely stored at the server, only a key is sent to the client. The whole session is serialized to a key which is then sent. I assume you want that user cannot tamper with the session cookies. You can use httponly cookies to prevent tampering. They are only handled by browser and cannot be accessed by user. This prevents cookie theft or session hijacking. You can enable httponly cookies with:
app.use(express.session({cookie: { path: '/', httpOnly: true}, secret:'password'}));
Still you should use some encryption to prevent eavesdropping of cookies. Use secure : true for that. You can also mention where you want to store the session with redis, mongo or simply in memory.
The request token validation that you mention is a technique commonly used to prevent Cross-site request forgery. It keeps changing the token dynamically to keep user from getting the token. You can use this in express with csrf middleware.
app.use(express.csrf())
IP matching will not work as IP of user can change over time.

PHP: Session Security

I read about session security eg. Session Fixation, Hijacking & Injection but am confused about the workings of session security. The way I usually do it:
// when user logins,
$_SESSION["user"] = "someuser";
// check user login
if (isset($_SESSION["user"]) && !empty($_SESSION["user"]))
Maybe I am doing it wrong, but I don't have Session IDs anywhere, or at least I didn't use it. Can someone explain how should Session IDs be used & how it affects session security? Also, is my understanding of the following threats correct?
Session Fixation
User visits link (http://site.com?session_id=123) and logs in
Server "marks" that session id as logged in
Hacker can now visit http://site.com?session_id=123
My understanding of Session Fixation seems very wrong to me. If its correct won't it mean that hackers can randomly use session ids and I will likely be used by an existing user?
Session Hijacking
Hacker somehow gets Session ID whether by Fixation or guessing etc
Session Injection
What is this?
You're not using session IDs explicitly, but PHP uses them automatically. The session ID is sent as a cookie to the browser, who sends it back to the server with every request to identify itself and resume the session. Without that, sessions are not possible.
A way to improve security is to regularly change the ID of a session, using session_regenerate_id(). That way, if a hacker acquires somebody's session ID, he has only a limited amount of time to abuse it.
Another way to prevent session hijacking (a hacker using your session ID to steal your session) is to store the client IP and user agent string when the session is opened and verifying that they haven't changed when resuming the session.
When using sessions, the session ID is the only information used to identify a session. Because of this, the session ID is a sensitive information.
Now both attacks, session hijacking and session fixation, aim for a valid session ID of a victim to gain access on that session. As for session hijacking, the attacker tries to obtain a victims session ID, and as for session fixation, the attacker tries to foist a prepared session on the victim.
To protect your application from those session attacks, there are two common safety measures:
protect valid session IDs, and
authenticate usage of sessions.
With PHP’s default session settings, the session ID is transmitted using a cookie (see session.use_only_cookies). You can protect this cookie by using a secure connection with SSL/TLS and by setting session.cookie_httponly to true so that the cookie can only be read when sent via HTTP and not by a client side program like JavaScript.
Additionally, you could authenticate the use of a session by associating a fingerprint of the client with the session. This could be a combination of user agent identifier and other request header fields.
Furthermore, you should change the ID of a session with every verification of authenticity or change of authorization. You can use session_regenerate_id(true) for this with an invalidation of the old session ID.

Resources