Trying to understand login systems and sessions - node.js

Im trying to understand how a user can keep logged (i'm trying to implement this on Node without frameworks, for learning). Just a couple of questions based on what i think i understand:
(1) When the user tries to login, it sends the user and password in an HTTP request body
(2) When data arrives to the server, it checks everything needed like if the user exists and if the password is correct
And here comes, i think, my problem: How can the user keep logged? The third step would be something like:
(3) The server create all the session data needed, encrypts and send it to the client?
(4) The clients store the encrypted data in the localstorage
(5) The credentials are sended with every request to the server, and the server decrypts it and check it before processing every user's action.
That's what i understand. But i find this very extrange. I feel i missing a lot... storing data in client side doesn't seems (at least for me) secure. Should the session data be stored on server-side? And how the username and password should be sended securely? It must be encrypted client-side? Is this secure? I think im looking for some pattern or i don't know. I feel lost.
Yeah, and sorry my bad english and poor knowledge. Im not asking for code and i will also appreciate any hint (like what to search in google, or a interesting blog) :)
Thank you, y un abrazo :)
--- EDIT ---
Well, finally i founded some usefull links and solved great part of my doubts :)
[http://stackoverflow.com/questions/6922145/what-is-the-difference-between-server-side-cookie-and-client-side-cookie][1]
[http://blog.codinghorror.com/protecting-your-cookies-httponly/][2]
[http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf][3]
[https://es.wikipedia.org/wiki/Cookie_(inform%C3%A1tica)][4]
[https://newspaint.wordpress.com/2015/09/06/how-to-get-cookies-from-node-js-http-response/][5]

1 and 2 are correct.
Sessions are usually implemented using cookies, not client-side local storage, because cookies are automatically sent to the server with each request. The cookie will often contain just a long randomly generated ID which refers to data stored on the server side, e.g. in a database. This data will identify the user and possibly store other session-level settings.
It is also possible to use a cookie with signed (and possibly encrypted) user information - for instance ASP.NET does this by default. This has the benefit that no storage is required for the session. The downside is that sessions cannot easily be destroyed from the server side. Therefore e.g. a feature that shows the user their currently active sessions (from other devices) and allows them to log them out couldn't be implemented.
Sending the username and password over the Internet should preferably be done securely, by using HTTPS. Do not implement your own encryption on the client-side. It will likely not work, plus the cookies themselves are viable to be stolen if the connection is not properly encrypted and authenticated.

Related

Is using JWT Tokens actually a secure way to work around user sessions?

I am trying to build a registration/login system using the PERN stack (Postgres, Express, React & Node) for a client website.
I was doing some researching and came across HTTP Cookie and JWT token authorizations (many more but apparently those two are the dominant).
I noticed alot apps and tutorials that uses Node JS seems to use JWT alot, and store these in localstorage. But I'm doubtful about the security because I feel like a developer can basically go into localstorage and get the JWT token which o
Is there a better way to secure user authentications with this stack or is using localstorage the rule of thumb? If so, why is that?
Thank you for your time.
One limiting medium to the security of both session IDs and JWTs is network transmission. In this case, both are only as secure as the network itself. But most likely, your application would be using something like HTTPS or SSL, in which case any data being sent across the network would be reasonably secure.
Regarding your other edge case of someone trying to sniff at a JWT in local storage, there are a few options you may consider:
First, the nature of the JWT is that it is generally tamper-proof. A JWT contains inside of it a checksum, which is a unique hash based on the actual contents of the JWT. Let's says that some malicious user sniffed local storage, and then tried to change e.g. the claims section of the JWT. In doing so, this would also change the checksum (which that user would not be able to figure out, lacking the server key). Then, the next time the compromised JWT is sent to the server, the server would reject it, because the computed checksum would not match with the value contained in the JWT.
Second, in the event the above be deemed not secure enough, it is possible to pass around encrypted JWT. If you go with this option, both the server and client would encrypt/decrypt before sending a JWT, which adds an extra layer of protection.
Security of network transmission is just one case of whole solution in web applications.
Im currently in the research of the same topic and as you said a lot of tutorials, blogs, youtube and other sources gives an excellent examples of using JWT tokens for handling user data. Unfortunately hardly anyone go deepest in handling and processing user sessions from administration point of view - where the real problems starts.
Logging the user in and sends JTW token in response to the client is not a problem at all. The problem begin when you as administrator want to invalidate a user.
Refer to this sources:
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
Logout/invalidate a JWT
The session cookie with session data stored in server-side is currently the best option for web application.

Cookie-challenges, storing logged in user

Hello fellow developers
I have obviously under estimated a thing when developing my first complex web site, where user creation and login is required.
It appears that cookies can be edited and modified by the user logged in, by using some developer tools i.e. in Google Chrome. That, I never gave a thought.
So, here is my issue.
When the user is logged in, I store the user name in a cookie.
If username-cookie is not blank, and I can find a user file with that name, the user is logged in, per se. Otherwise, no user is logged in.
When the user logs out, I simply expires the cookie, which works fine.
Now, the problem is, that a user obviously can edit the content of a cookie, outside the web application, or with javascript.
What would be the correct approach here to ensure, that the username cookie is not compromised in any way, other by my web application?
Making them read-only is not possible, I assume. Encrypting the cookie and then decrypting might work, I guess. Then, the cookie would be nonsense to the user, and if modified, result in a logout, as no valid username can be found upon decrypting the edited cookie.
I have stalked Googles cookies, and it appears that there are a lot of xxID cookies, which contains garbage. Does that mean, that encrypting/decrypting is the only way to make it work? I also considered some kind of login-ticket, but that would require a table lookup every time a user interacts with my web page.
Can anyone give me a hint as to what would be the correct approach?
Thanks in advance
Best regards,
Karsten Heitmann
You should look up session management for the language you are using.
The traditional approach is that when a user logs on, your application generates a long, cryptographically random token called the "session id" and sets that into a cookie. It stores data like who is logged in on the server side identified by the random value, so when a logged on user comes back, the browser sends the cookie with the random session id and the application can look up session data on the server side. This way an attacker has no way to guess a valid session id for a logged on user, assuming the session id is cryptographically random and long enough (which more precisely means it has enough entropy). Logging out means deleting the session data on the server side, and also removing the cookie, but that is not the most important part - the session will be invalid anyway.
Note that you should not code this yourself. You did not mention the language and environment you are developing in, but session management is rather tricky business if you want to secure it, and it is already provided by most languages / frameworks.
Just for curiosity, the encryption approach you mention is by the way a valid one. Some frameworks actually do that, but you should not attempt to code that either, because it is very easy to get it wrong, lots of things need to be taken care of to make it secure enough. Unfortunately an answer here is not the right format to go into details I'm afraid.
Btw you mention looking at Google. They use their own single sign-on solution, it is very complex compared to simple session management, so it's probably not the best example for you to look at. Find simple websites, most of those work the traditional way.

HTTPS or other clever authentication methods

A little background: I am going to be constructing a webserver, likely the most up to date version of apache when I get around to it. It is going to be updated with sensory information from a makeshift security system I have.
As a counterpart, I am designing an app to go along with it, that will automatically contact the webserver and pull the sensory information about once every 1.5 minutes.
I want to have an authentication method so that the average Bob can't see this information, mostly due to the fact that there will be some command and control as part of the server as well.
The question: I feel like a simple username and password is the wrong way to go about this since it isn't dynamic and theoretically seeing the same credentials sent that frequent could be dangerous, so is there any other authentication method that could mitigate this?
The question pt. 2: Obviously I want an encrypted channel, will https stumble over itself if it tries to renegotiate every minute and a half?
I haven't begun this project yet much less chosen any language to write it in, meaning I am super open minded to suggestions, any help is greatly appreciated.
The question: I feel like a simple username and password is the wrong
way to go about this since it isn't dynamic and theoretically seeing
the same credentials sent that frequent could be dangerous, so is
there any other authentication method that could mitigate this?
You could use Google Sign-In to allow log on via a Google account.
Or you could implement two factor authentication with say Google Authenticator or via SMS to prove that the user logging in has more than one factor of authentication. These factors could be:
Something you know (e.g. password)
Something you have (e.g. phone that provides a One Time Password)
Edit: Having re-read your question - yes you are fine to authenticate with username and password (over HTTPS), however you should then store a session identifier client-side and simply send this in future rather than the username/password each time. This is more secure as it can be stored safely client-side, and if exposed the identifier can be easily revoked.
The question pt. 2: Obviously I want an encrypted channel, will https
stumble over itself if it tries to renegotiate every minute and a half?
Nope, this is what it is designed for. Browsers will keep open an HTTPS connection for a length of time. Additionally, they will use session resumption rather than executing a full HTTPS handshake in the case that a new connection needs to be established. Session resumption is much quicker than establishing a completely new session. See this article on the CloudFlare blog for more info.

How to use Passport with Node.js and MongoDB securely?

So I've gotten Passport to work with Node.js and MongoDB for session management which of course conveniently provides access to the user object in the request header. However, at least for me, Passport sets this object to be the entire account document from MongoDB. For the schema I've created, this includes everything about the user - email, name, hashed and salted password etc. So I have two questions about this.
First of all, is it really secure to send all that info back and forth between server and client over and over again? Sure it's sent over SSL and the password is hashed and salted - but all the user info is still in there. Should my schema demand user info (personal info not needed for authentication) be kept in a different MongoDB document? Even if I did that, the hashed password would still be passed back and forth. Is it assumed that SSL prevents that data from being eavesdropped? It just seems that if someone hypothetically managed to suck up every header sent to my app, they could just recreate the user database and perform a rainbow table attack.
Second of all, on the server side, I've (naively?) been using the request header username element (req.user.username) to determine which user is connected and authenticated. But, it seems that if a user just changed their header to be a different username, my code would allow them to masquerade as a different user. So should I be verifying the identity of the request by another means, instead of just using the plaintext username available? Or am I completely off the mark as to how these headers are stored, generated, and passed, and this isn't actually a security issue? If so - can someone elaborate a bit on how these headers from Passport are actually created?
For your first question, no, it is not ok to send everything (including password hash) to the user, that would beat its purpose and as you said and very well, once you someone had the hash, would be much easier to do a brute force attack (you don't that data to be exfiltrated from your app)
As for the second question, you should have some middleware or plugin that validates that the cookie present on the request is actually valid and generated by you in the first place, it is ok to use req.user.username for Authorization purposes in route handles once you validated that the user has previously Authenticated in your system (through the cookie)
Be sure to check out this blog post on how to build secure express apps https://blog.liftsecurity.io/2012/12/07/writing-secure-express-js-apps but in case you are still considering which framework to use, I would take a look at Hapijs and its bell plugin for authentication and https://github.com/hapijs/hapi-auth-cookie to keep session.
Good luck! :)

Is this safe for client side code?

I'm writing a GWT application where users login and interact with their profile. I understand that each form entry needs to be validated on the server, however, I am unsure about potential security issues once the user has logged in.
Let me explain. My application (the relevant parts) works as follows:
1 - user enters email/pass
2 - this info is sent back to the server, a DB is queried, passwords are checked (which are salted and hashed)
3. if the passwords match the profile associated w/ the email, this is considered success
Now I am unsure whether or not it is safe to pass the profile ID back to the client, which would then be used to query the DB for information relevant to the user to be displayed on the profile page.
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
-Nick
What you are dealing with here is a session management issue. Ideally, you want a way to keep track of logged in users (using random values as the session key), know how long they have been idle, be able to extend sessions as the user is using the site, and expire sessions.
Simply passing the profile ID to the client, and relying on it to send it back for each request is not sufficient - you are correct with your concern.
You want to keep a list of sessions with expiration times in a database. Every time an action is executed that needs user permissions (which should be pretty much everything), check to see if the session is still valid, if it is, extend it by however long you want. If it is expired, kill the session completely and log the user out.
You can store your session keys in a cookie (you have to trust the client at some point), but make sure they are non-deterministic and have a very large keyspace so it cannot be brute forced to get a valid session.
Since you're logging a user in, you must be using a backend that supports sessions (PHP, .Net, JAVA, etc), as Stefan H. said. That means that you shouldn't keep any ids on your client side, since a simple id substitution might grant me full access to another user's account (depending on what functionality you expose on your client, of course).
Any server request to get sensitive info (or for any admin actions) for the logged in user should look something like getMyCreditCard(), setMyCreditCard(), etc (note that no unique ids are passed in).
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
Stefan H is correct that you can solve this via session management if your session keys are unguessable and unfixable.
Another way to solve it is to use crypto-primitives to prevent tampering with the ID.
For example, you can store a private key on your server and use it to sign the profile ID. On subsequent requests, your server can trust the profile ID if it passes the signature check.
Rule 1 - Avoid cooking up your own security solution and use existing tested approaches.
Rule 2 - If your server side is java then you should be thinking along the lines of jsessionid. Spring Security will give you a good starting point to manage session ids with additional security features. There will be similar existing frameworks across php too (i did not see server side language tags in the question).
Rule 3 - With GWT you come across javascript based security issues with Google Team documents and suggests XSRF and XSS security prevention steps. Reference - https://developers.google.com/web-toolkit/articles/security_for_gwt_applications

Resources