PHP recommendations for user authentication and password security

What are the best current libraries / methods for authenticating users without using a CMS or heavy structure?

The answers should include suggestions for everything that you think should be considered the standard for new PHP development, including user authentication.

+43
authentication php
Oct 26 '09 at 13:39
source share
8 answers

OpenID is a method of authenticating users based on existing accounts on shared web services such as Yahoo, Google and Flickr.

Logging in to your site is based on successfully logging in to the remote site.

You do not need to store user confidential information or use SSL to protect user login.

The current version of the PHP library can be found here .

+29
Oct 26 '09 at 13:49
source share

I am using OpenID .

But, like stackoverflow, I am using the Google openid-selector project to do a heavy lifting.
Demo page here .

The obvious advantages (OpenID) are.

  • You do not have to be a security expert.
  • Users trust large sites with their information.
  • You can request things like (alias, etc.), but the user must choose.
  • You need not worry:
    • registration processes
    • lost / forgotten password
+11
Nov 04 '09 at 6:42
source share

Implementing user authentication is safe without relying on a framework (or a third-party library such as OpenID) to do this for you and not a trivial undertaking.

When looking at 10,000 feet, you need to decide:

  • Do you have usernames, email addresses, or user IDs as your primary selector?
  • How to store passwords? PROTIP: password_hash() or scrypt is the way to go.
  • How should you handle the Remember Me checkboxes? There are many bad strategies on the Internet. Be skeptical of each of them, because they can introduce vulnerabilities into your application.
  • How should an application handle users who have forgotten their password?

The information contained in this answer is current and relevant as of May 9, 2015 and may be outdated after concluding a password hash

Primary selectors

In general, usernames and email addresses are better than ID numbers.

There should not be any security requirements to keep usernames a secret, because in practice they will leak out when someone tries to register anyway.

You can decide whether to consider email addresses as secret. Usually users are not exposed to spammers, scammers and trolls.

Password hashing

You should use password_hash() and password_verify() if you are not experienced enough in writing cryptographic libraries to go up and on.

Beyond bcrypt

Sometimes developers like to create creativity (for example, add “pepper”, which usually means pre-hashing or HMACing passwords with a static key) and goes beyond standard implementations. We did it ourselves, but very conservatively.

For our internal projects (which have a much higher level of security than most user blogs), we wrote a wrapper around this API called PasswordLock , which first hashes the password with sha256 , then base64 encodes the original hash output, then transfers this hash to the hash base64 code in password_hash() and finally encrypts the bcrypt hash code with a properly implemented encryption library .

To repeat, instead of pepper, we encrypt password hashes. This gives us great flexibility in the event of a leak (we can decrypt and then encrypt again, because we know the key). In addition, we can run our web server and database on separate equipment in one data center to reduce the impact of SQL injection vulnerability. (To start cracking hashes, you need an AES key. You cannot get it from the database, even if you are running into the file system.)

 // Storage: $stored = \ParagonIE\PasswordLock\PasswordLock::hashAndEncrypt($password, $aesKey); // Verification: if (\ParagonIE\PasswordLock\PasswordLock::decryptAndVerify($password, $stored, $aesKey)) { // Authenticated! } 

Password vault with PasswordLock :

  • hash('sha256', $password, true);
  • base64_encode($step1);
  • password_hash($step2, PASSWORD_DEFAULT);
  • Crypto::encrypt($step3, $secretKey);

Password Verification with PasswordLock :

  • Crypto::decrypt($ciphertext, $secretKey);
  • hash('sha256', $password, true);
  • base64_encode($step2);
  • password_verify($step3, $step1);

additional literature

+10
May 10 '15 at 2:44
source share

There are a lot of great answers here, but I feel it’s worth saying this - DO NOT try to invent a wheel in this case! It is very easy to damage user authentication in various ways. If you really need a special solution and have firm knowledge of the circuits and best security practices, you will almost certainly have security flaws.

OpenID is great, or if you are going to minimize yourself, at least use the created library and follow the documentation!

+9
Nov 09 '09 at 19:11
source share

PHPass is a lightweight variable-value hash variable library using bcrypt.

Variable value means that you can subsequently increase the "cost" of hashed passwords to seamlessly increase security without having to revoke your previously hashed user passwords.

The size of the field used to store the hash is constant even when the "cost" increases due to an increase not in the size of the hash, but in the number of iterations needed to create it.

+7
Oct 26 '09 at 13:46
source share

Login using HTTP AUTH

After authentication for PHP, you just need to use $_SERVER['PHP_AUTH_USER'] to get the username used during authentication.

This can be a faster and sometimes more flexible solution than processing the solution at the scenario level, provided that the user requires limited information, since all that is available to you is the username used to log in.

However, forget about integrating your HTML authentication if you don’t include the full HTTP AUTH scheme from the scripting language (as described below).

Moving native HTTP-AUTH in a scripting language

In fact, you can extend HTTP Basic Auth by emulating it in your scripting language. The only requirement for this is that your scripting language must be able to send HTTP headers to the HTTP client. A detailed explanation of how to accomplish this using PHP can be found here: ( more on PHP and HTTP AUTH ).

You can expand the article above using a typical authentication scheme, file storage, even PHP sessions or cookies (if the information is not needed to be permanent), giving you more flexibility when using HTTP AUTH, but at the same time preserving some simplicity.

Disadvantages of HTTP AUTH

  • The main disadvantage of HTTP authentication is the complications that can occur when you log in. The main way to clear a user session is to close the browser or pass the header with 403 authentication. Unfortunately, this means that the HTTP AUTH pop-up message returns to the page, and then requires users to either log in or delete the cancel. This may not work when considering usability, but it can be used with some interesting results (i.e., using a combination of cookies and HTTP AUTH to store state).

  • The processing of HTTP HTTP headers, sessions, and HTTP headers is determined by the browser implementation of the standard. This means that you will stick to this implementation (including any errors) without the possibility of a workaround (unlike other alternatives).

  • Basic auth also means that auth_user and password are displayed in the server logs, and then you must use https for everything, because otherwise the username and password are also transmitted over the network with each request in plain text.

    / li>
+5
Nov 03 '09 at 15:40
source share

It is important to separate the security level of your application from the rest. If there is no distance between your application logic and your communication system, you can communicate freely in one place and safely somewhere else. Perhaps you make a mistake and send the password in an unencrypted cookie, or maybe you forget to confirm the user credentials in one step. Without the “right way” to communicate with the user, you will definitely make a mistake.

For example, let's say you are now checking users:

 user_cookie = getSecureCookie() if (user_cookie.password == session_user.password) { do_secure_thing() ... } 

If a vulnerability is found in getSecureCookie () and you use this code to validate users throughout the application, you may not find all instances of getSecureCookie () that need to be fixed. If, however, you separate your logic from your security:

 if (userVerified()) { do_secure_thing() ... } 

... you can quickly and easily recover your application. Give yourself the “right path” to ensure security, and you will be much less likely to make a serious security mistake.

+4
Nov 09 '09 at 21:43
source share

The best authentication is the use of multi-factor authentication, ideally - without tokens - the version in all protected confidential inputs.

Password protection and easier to use with high reliability and security. There are several available outside of EMC / RSA. I prefer SwivelSecure PINSafe.

Igor S

+1
Mar 07 '13 at 15:36
source share



All Articles