-1

I've decided to implement a simple, custom authentication system on my own for my web application: when a user logs in, I'll store their "user_id" in either a session or cookie.

If I choose cookie, I'd need to encrypt "user_id".

Nonetheless: What's the difference between storing in one versus the other for the authentication purpose? Which is more secure? Why? What's recommended? What should I pay attention to when doing so?

  • In security "don't roll your own", needless to say cookies are used to maintain logged user's session – elsadek Sep 26 '17 at 8:48
  • @elsadek, I'm ok with rolling my own. I know that cookies are used and that has nothing to do with my question. – Jori Sep 26 '17 at 9:37
  • I'm confused, how are you defining 'session' as something in which you can store something? Cookies store things. Sessions is a logical concept. – schroeder Sep 28 '17 at 9:27
  • 1
    You may be OK with rolling your own, but the nature of your question demonstrates why you should reconsider. You may be under estimating what you gain by not re-creating this particular wheel and leveraging mature libraries, frameworks, etc. – Thomas Carlisle Sep 28 '17 at 14:52
3

You are comparing oranges and apples here, or more exactly, bricks and houses. What identifies a conversation is by definition a session. Full stop. But the session can be implemented in various ways:

  • server-side data and a session id stored in a cookie (most common way nowadays)
  • server-side data and a session id transported as a URL parameter (used to be common when users used to reject cookies)
  • data stored in a cookie (limited to 4k) - uses fewer server resources
  • maybe others...

Not all frameworks allow all session implementations.

Back to your question, from a security point of view, data that does not leave the server is expected to be harder to tamper, because it is trivial to build a custom cookie through any HTTP client library. So you should at least sign the cookie and control the signature on each pass, and if you do not want to leak internal data from the application you should also encrypt the cookie content. This, and the added limitation of 4k for a cookie size, is enough to explain why the session data is generally kept server side with only an id passed in a cookie.

TL/DR: unless you have a strong reason not to do so, my advice would be to stick to the common usage and store the user id in a server-side session: that's probably the default way for your framework...


Detailed answer:

What's the difference between storing in one versus the other for the authentication purpose?

No difference on a functional point of view because both are different implementations of a session

Which is more secure? Why?

Using a session is more secure because it will rely on a heavily tested framework or library. Server side session is more robust because cookie sessions rely on additional keys for signature and/or encryption and key management is an additional point to consider in a security point of view

What's recommended?

Definitely session, because it is provided by your framework or library, and most security problems come from the implementation. That's the reason why security best practices recommend don't roll your own

What should I pay attention to when doing so?

You cannot rely on what you do not control, so you cannot expect that a cookie has not been tampered with client side. So you must sign the cookie at the application level with a strong and securely managed key. The internal user id is normally not relevant for the client, so you should encrypt it still at the application level, and still with a strong and securely managed key. You must add additional controls, still at the application level to make sure that the cookie (even signed and encrypted) has not been spied on from a legitimate previous session, so you must at least store the session id inside your specific signed cookie. And there may be other possible problems I have not thought about...

  • I know. There's a cookie installed on a user machine with session_id anyway. why not install the same encrypted cookie with user_id, what's the difference in terms of security? – Jori Sep 27 '17 at 0:05
  • I meant, why not install one more encrypted cookie with user_id – Jori Sep 27 '17 at 11:22
  • If you can make sure that it is correctly encrypted, with a correct implementation of a robust algorythm and if you can make sure that both the encryption key and the signature key are not trivial and will not be inadvertently or maliciously leaked, then you have the same level of security as a server side session. One rule in security says don't roll your own. – Serge Ballesta Sep 27 '17 at 12:39
0

It is better to store that kind of data in the session.

The cookie its suceptible to get stolen by the client side perspective, it's possible to bruteforce it or get sniffed in the network.

As recomendation on what to pay attention be always concern in what the clients can input. I agree with you in rolling your own, it gets you to understand what is really happening.

  • in cookie it'll be encrypted, what's the difference? – Jori Sep 26 '17 at 13:57
  • Do you mean in session? – EdCapetti Sep 26 '17 at 14:48
  • no................ – Jori Sep 27 '17 at 1:18
0

Be careful with your use of language. In both scenarios you are storing session data - the difference is that in one case you are storing it on the server and in the other at the client.

If the user id is stored in a cookie then, even if it is encrypted, it is possible for someone else to copy the data and impersonate the authenticated user. If the cookie only contains a reference to data held serverside, then this is still possible, however there is a bounded window of opportunity defined by the authenticated session - once it expires it cannot (or more commonly should not) be resurrected.

There are some arguments for storing session data in a client to do with performance and scalability. From a security viewpoint, one could argue there is some benefit in not leaving a footprint of the users data on a server (but this is not a very good argument as you can achieve this by encrypting on the server using a key stored at the client).

If you are storing authentication data client side you need to do more to protect it - communications must be exclusively over HTTPS, an expiry time and the authentication token must be encrypted in the dataset (and both must be validated for authentication).

Unless you have a compelling reason for keeping session data on the client, just follow the crowd and store it on the server with only a non-enumerable, self-expiring reference to the session at the client.

-1

I think there may be some confusion regarding what a Cookie and what a Session does. As @elsadek points out, the cookie usually stores a session ID, which in turn is used server side to retrieve the associated data, in your case, a user ID.

The server (with enabled session handling) checks whether a Cookie is attached to a request, and if not, returns a Set-Cookie header, typically containing a session ID. The browser picks this up and will now subsequently pass the session ID as a Cookie back to the server.

This enables the server to associate data with a browser session, hence the name "session".

So: Store your User ID in the session data. And: Don't roll your own. There are tons of libraries, disregarding your framework, which do this for you.

  • Reason for downvoting? Genuinely interested. – donmartin Sep 27 '17 at 13:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.