Is this a suitable registration and registration system

Apparently, hashing the username and password and saving them as cookies and logging in using disinfected cookies is not enough for you people (or the security of my site).

Is this approach good enough?

Registration Procedure:

$salt= date('U'); $username= hash('sha256', $salt. $_POST['username']); $password= hash('sha256', $salt. $_POST['password']); $token = hash('sha256', $salt. (rand(1,10000000000000000000000000000000000000000000))); 

To enter the system manually, users enter their username and password, they are transmitted through a hash and are mapped.

After a successful login, two cooking files are created for the user. One of them contains an unconfirmed username, and the other contains a hashed token.

When a user visits, if cookies are set, the site hashes the username and then uses these two values ​​to enter.

The advantage of this approach is that it allows you to avoid saving the user's password anywhere on your computer. Someone can hack a token and gain access to their account, but at least I would not compromise the user's password ...

People who answered the MySQL real_escape string and cookies say that it is incorrect to store user data in cookies. Does this distract the problem?

+4
source share
4 answers

Why do you need to store a password in general, even an encrypted version? Is your site accessing a third-party API in a backend that runs HTTP Basic auth or something else?

Unfortunately, there is no final answer to your question. “Suitable” means different things to different people. And with security issues, I'm not sure that it is ever possible to be “sufficiently suitable” or “sufficiently safe”. However, here I handle logins and password security. In my users database, I have 3 columns related to registration:

  • Username
  • salt
  • passwordHash

The username column is in plain text. The salt column is a 64-character string of randomly selected alphanumeric characters. The passwordHash column is the user password associated with their salt value and then hashed irreversibly. I use sha256 for my hashes. Salt is 64 characters, because that is what sha256 produces. It's good to have a salt value, at least as long as the hash to get enough variability in the hashed string.

When a user submits a login form, I make a database request for the username. If the username is not found, I am showing the user the error "Invalid username and / or password." If the username is found, I combine the salt with the password, the hash file and see if the passwordHash value matches. If not, the user will be shown exactly the same error.

It is good to show the same error message regardless of whether the username was incorrect, or the password was incorrect, or both. The fewer hints you give the hacker, the better. In addition, whenever a user changes his password, I also give them a new salt . It is really easy to do at that point in time, and it keeps the salt values ​​a little fresher.

This system, having a different salt for each user, is called dynamic saltation. This greatly complicates the work of a hacker if they try to use rainbow tables to reverse engineer user passwords. Not to mention that storing passwords in an irreversibly hashed form has a very large way for someone to determine the user's password, even if they have access to the database and PHP code.

It also means that your user forgets his password and there is no way to retrieve it. Instead, you only write your system to reset to a new random value, which is sent to them along with a strong promotion to change the password as soon as they log in again. You can even write your system to force it the next time you log in successfully.

I need passwords to be at least 8 characters long. Ideally, it should also include numbers and special characters, but I have not decided yet what it should require. Maybe I should!

To protect against brute-force attacks, I track all failed logins for the previous 10 minutes. I track them for every IP address. After 3 failed login attempts, the system uses the sleep() function to delay the response to further login attempts. I use the code block as follows:

 $delay = ($failedAttempts - 3); if ($delay > 0) { sleep($delay); } 

IMHO is much better than blocking users from their accounts after a hard number of crashes. This reduces the number of customer support requests you receive, and is more graceful for legitimate users who simply cannot remember their own passwords. Brute-force attacks must make many attempts per second in order to have some kind of efficiency, so a delay based on n = x does not allow them to get very far.

Input sessions are tracked using PHP sessions. Call session_start() when every page of your site loads. (This is very simple if you have a common header.php file.) This makes the $ _ SESSION variable available. When a user successfully logs in, you can use it to store the information your site needs to know that the user is logged in. I usually use their user ID, username, and possibly some other site specific details. But I do not include a password or hash here. If somehow the hacker got into the user session data stored on your server, they still will not be able to find the user password in this way.

Logging out occurs when one of two things happens: Either 1) A cookie is deleted from the user's session, for example, by clearing the browser’s cache, and sometimes just closing the browser window, or 2) The server will delete its session data. You can make the latter happen by calling session_destroy() when the user clicks the "Logout" button on your site. Otherwise, you can force the sessions to automatically expire after a certain period of time. This may include setting session.gc_* parameters in php.ini .

If you must know the user password after the initial login phase, you can save it in $_SESSION . DO IT IF AND ONLY IF your site requires an SSL connection, and you did this to prevent the site from working without it. Thus, the password is encrypted and protected from sniffing packets . But be aware that this is a security risk if a hacker gains access to your server session data.

+5
source

Your salt is not random enough.

The problem with this is the replay attack. Suppose a bad guy collects user cookies on the way to your site. What prevents him (the bad guy) from sending the same values ​​and falling as if they were a genuine user?

It is bad to store user data in cookies. What can go away for you is to store one random 64-bit number in a cookie in the user's browser. In the application authentication database, you record random numbers and basic properties, such as the username, the time the cookie was first valid when it expired, and possibly the browser information and IP address information.

When a cookie is sent, you acknowledge that it appears to come from the same browser as when sending the cookie.

I have not tested this based on best practices or what is needed to “authenticate” the user again. But random data does not contain anything meaningful, so this is not the end of the world if a bad guy captures him. The validity of the captured cookie is limited, and the bad guy should imitate the user environment fairly accurately if you catch the relevant details.

+1
source

Why hash username? This is not a secret, and you will need an unhashed (or at least unsalted) username to find login credentials anyway.

In addition, I think you will want to use a cryptographic RNG, for example openssl_random_pseudo_bytes() instead of rand() . Other than that, the basic idea looks fine.

0
source

If I was a malicious user on an open network, for example, a wi-fi access point, and wanted to gain control of one of your user accounts, I could try the following approaches. Protect yourself.

  • Knowing (from your post on SO) that you are using the date ("U") as your salt, I tried to crack the password using a dictionary by adding a known salt before each test.
  • If you allow unencrypted traffic, I would sniff the traffic and grab the token. I hope your site will provide an opportunity to change my email address, and then send me an email password.
  • If I can access the file, I would extract the token from the file and use it directly.

Another approach you can consider is to serialize the fields, encrypt this string, and then save the base64 encoded message in your cookie. Also, add some large messy string to your existing salt.

0
source

All Articles