Session-less system authentication - Cookies only - Is it secure enough?

I am interested in your advice / opinions on this security issue.

I was thinking of doing something like this:

  • Get the hash MAC (sha256) from a string built from userId + expirationTime, and as a secret key string built from some secret string and $ _SERVER ['HTTP_USER_AGENT'].
  • Get the hash MAC (sha256) from userId + expirationTime and as the secret key previously made by the hash (from step 1).
  • String line from userId | expiration | and a previously made hash (from step 2).
  • Encrypt the specified string (from step 3) using the rijndael-256 almanac. (mcrypt family of functions).
  • Encode to base64.
  • Set a cookie with the given value.

What do you think. This is normal? What else could I implement with checking $ _SERVER ['HTTP_USER_AGENT'] to make sure the cookie is not stolen (except for the IP address)?

PS Of the confidential data, the cookie will only contain userId.

EDIT: Good to clarify some things. I am trying to make a "safe" auth system that does not rely on sessions. The application in question is built more or less as a clean soothing api.

Step 2:

Problem: “The Fus protocol does not answer this question. The Fus prototype has only one key, col, namely the server key. One simple one is to use this server key to encrypt the data field of all cookies; however, this solution is unsafe.”

Solution: “Our solution to this problem is simple and effective. We suggest using HMAC (username | expiration time, sk) as an encryption key. This solution has three good features. Firstly, the encryption key is unique for each cookie from per user name and expiration date. Please note that whenever a new cookie, a new expiration time is included in the cookie. Secondly, the encryption key is irreplaceable because the server key is kept secret. Thirdly, the key for each cookie is not requires server side or vn wipe the cookie, rather, dynamically created by the server. "From the article" Secure Cookie Protocol "by Alex X. Liu1, Jason M. Kovacs

Step 4: Encrypts the data (which would look something like this: " marko@example.com | 34234324234 | 324erfkh42fx34gc4fgcc423g4") so that even the client cannot know exactly what is inside.

Step 5: Base64 encode just to make the final value pretty.

+6
source share
2 answers

I will bite.

To maintain some semblance of state, you need to identify the user using a key of some type. This key is sent to the browser as a cookie OR via the query string parameters.

Now, verification of this key can occur inside the web server (session) itself or by checking another storage mechanism, usually a database record.

The key itself must be confused using some mechanism. The reason for obfuscation is simply to complicate what values ​​other keys may have if the original user or someone else decides to check the value. For example, if the key is your user ID (not recommended), and you use incremental ints, then it is trivial to guess the other user keys. I want to emphasize that obfuscation (or even direct encryption) key provides absolutely no protection from the captured session. Everything he does makes it difficult to guess the keys of other people's sessions .

However, I believe that the key should not have anything to do with your user ID and, instead, be next to a random value, such as a generated GUID. Quite frankly, the 64-based GUID is at the same level of security as encryption of the user ID + time. It is just that your server has a more intensive computing process than another.

Of course, this key may change for each request. The browser says something, you create a new key and send it back. If the browser sends an outdated key, write it down and drop it back to the login screen. This should prevent re-attacks .. to some extent. However, it introduces other problems, such as using the back button in different browsers. Thus, you may not want to go this route.

However, you cannot depend on the IP address of the client, because the same user can send subsequent requests using a different IP address. You cannot depend on the fingerprint of the browser, because any decent hack tool will capture this and send the same values ​​no matter what they use.

Now, if you really want to do it right, you must enable SSL. Otherwise, you are wasting your time. The whole conversation (from the login screen) must be encrypted. If this is not the case then someone can simply listen to this cookie, immediately play it back and capture the session. The fact is that they do not need to know the values ​​contained in them in order to use them. So all this is hashing, etc. You just have fluff that will increase the load on your server.

I said that I use SSL ?;) This will encrypt the traffic from the beginning of the conversation, and the attacker will not be able to play the same packets as for their own handshake with the server. This means that all you have to do is make sure that any session ID that you use is not valid so that one user cannot accept another session.


So to summarize: the method you posted is a waste of time.

You are much better off getting a $ 10 SSL certificate and using a 64-bit GUID as a session identifier. How you store session information on your server doesn’t matter much ... except in situations with load balancing. At this point, it should be idle and supported by the database server. But this is another question.

+10
source

@Marko A few comments on how secure this session-in-cookie approach is:

First of all, as others say, you need a secure connection. This requirement does not exist. It's necessary.

In addition, there are many errors associated with the implementation of a secure encryption / authentication system. For example, you need to make the MAC check "constant time", you need to pay attention to how you implement encryption / authentication (operating mode, creating IV, etc.). Etc.

If you are not sure about these issues, I recommend you take a look at TCrypto (which I support):

TCrypto

This is a small key storage library with PHP 5.3+ key values ​​(by default, cookies will be used as a storage backend). Designed specifically for the (scalable) use of the "session in cookie". Feel free to use it :) Also, if you are interested in a low-level implementation, take a look at the code. The code base is not so huge, I think it will be very good, demonstrating the use of code related to the use of encryption in PHP applications.

+1
source

Source: https://habr.com/ru/post/892371/


All Articles