Php login security best practices

I am wanting to re-write my login scripts for clients websites to make them more secure. I want to know what best practices I can implement into this. Password protected control panels are in their abundance, but very few seem to impliment best practices in terms of code writing, speed and security.

I will be using PHP and a MYSQL database.

I used to use md5, but I see that sha256 or sha512 would be better [together with secure hash and salt].

Some login scripts log the ip address throughout the session or even the user agent, but I want to avoid that as it isn't compatible with proxy servers.

I am also a little behind the best practice in using sessions in PHP 5 [last time I read up was PHP 4] so some best practices with this would be helpful.

Thanks.

asked May 2, 2011 at 15:53

baritoneukbaritoneuk

3831 gold badge4 silver badges6 bronze badges

2

The best think is to not reinvent the wheel. But, I understand, in PHP world it may be difficult to find a high quality component which already does that [even I'm pretty sure that the frameworks implement such things and their implementations are already tested, solid, code-reviewed, etc.]

If, for some reasons, you can't use a framework, here's some suggestions:

Security related suggestions

  • Use PBKDF2 or Bcrypt if you can. It's done for that.

    Rationale: both algorithms can make the hashing process arbitrarily slow, which is exactly what you want when hashing passwords [quicker alternatives mean easier brute force]. Ideally, you should adjust the parameters so that the process becomes slower and slower over time on same hardware, while new, faster hardware is released.

  • If you can't, at least don't use MD5/SHA1. Never. Forget about it. Use SHA512 instead, for example. Use salt too.

    Rationale: MD5 and SHA1 are too fast. If the attacker has access to your database containing the hashes and has a [not even particularly] powerful machine, brute-forcing a password is fast and easy. If there are no salts, the chances that the attacker finds the actual password increases [which could make additional harm if the password was reused somewhere else].

  • In PHP 5.5.0 and later, use password_hash and password_verify.

    Rationale: calling a function provided by the framework is easy, so the risk of making a mistake is reduced. With those two functions, you don't have to think about different parameters such as the hash. The first function returns a single string which can then be stored in the database. The second function uses this string for password verification.

  • Protect yourself from brute force. If the user submits a wrong password when she already submitted another wrong password 0.01 seconds ago, it's a good reason to block it. While human beings can type fast, they probably can't be that fast.

    Another protection would be to set a per-hour failures limit. If the user submitted 3600 wrong passwords in an hour, 1 password per second, it's hard to believe that this is a legitimate user.

    Rationale: if your passwords are hashed in an insecure way, brute force can be very effective. If passwords are stored safely, brute force is still wasting your server's resources and network bandwidth, causing lower performance for legitimate users. Brute force detection is not easy to develop and to get right, but for any but tiny system, it's totally worth it.

  • Don't ask your users to change their passwords every four weeks. This is extremely annoying and decreases security, since it encourages post-it-based security.

    Rationale: the idea that forcing passwords to change every n weeks protects the system from brute force is wrong. Brute force attacks are usually successful within seconds, minutes, hours or days, which makes monthly password changes irrelevant. On the other hand, users are bad at remembering passwords. If, moreover, they need to change them, they will either attempt to use very simple passwords or just note their passwords on post-its.

  • Audit everything, every time. Store logons, but never store passwords in audit log. Make sure that the audit log cannot be modified [i.e. you can add data at the end, but not modify the existing data]. Make sure that audit logs are subject to regular backup. Ideally, logs should be stored on a dedicated server with very restrictive accesses: if another server is hacked, the attacker will be unable to wipe out the logs to hide his presence [and the path taken during the attack].

  • Don't remember user credential in cookies, unless the user asks to do it [“Remember me” check box must be unchecked by default to avoid human error].

Ease of use suggestions

  • Let the user remember the password if she wants to, even if most browsers are already this feature.
  • Don't use Google approach when instead of asking for user name and password, the user is asked sometimes for password only, the user name being already displayed in a . Browsers can't fill the password field in this case [at least Firefox cannot do that], so it forces to logoff, then to logon with an ordinary form, filled by the browser.
  • Don't use JavaScript-enabled popups for logon. It breaks browsers password-remember features [and sucks in all cases].
  • Let the user enter either her user name or her mail address. When I register, sometimes the user name I want to enter is already taken, so I must invent a new one. I have all chances to forget this name in two hours.
  • Always keep a link to "Forgot my password" feature near the logon form. Don't display it only when the user failed to log on: the user who don't remember her password at all have no idea that she must submit a wrong one in order to see the "Forgot my password" link.
  • Don't use security by post-it.
  • Don't invent stupid rules related to the password in order to make it weaker. Example: "Your password must start with a lowercase letter."; "Your password cannot contain spaces."

answered May 2, 2011 at 16:36

Arseni MourzenkoArseni Mourzenko

134k31 gold badges338 silver badges504 bronze badges

10

  1. Your site should use HTTPS. At no point should you present a login page or accept logins from a non-encrypted connection.
  2. Your cookies should be restricted to HTTP-only and be restricted to secure connections if you use HTTPS.
  3. The login process should take no less than 2 seconds [1 if you think 2 seconds is too long]. Use a secure hash when storing and verifying passwords, and use a salt that is harder to guess. Use bcrypt if possible. Otherwise, use some other kind of iterated hash.
  4. Never ever compose your database queries in any way that requires using functions like mysql_real_escape_string. Never use string concatenation to craft your query. Use prepared, parametrized queries. Most, if not all, DB drivers for PHP support it. If you don't know how to do it, spend some time learning how to prepare, bind, and execute using whatever DB you're using. It's the only sure way to guard yourself against SQL injection. PDO supports this.
  5. Encourage your users to not use the same password they use for their email. Remind them that if your site is compromised and if they use the same password in both places, someone can hijack their email.

answered May 2, 2011 at 16:41

greyfadegreyfade

11.1k2 gold badges39 silver badges43 bronze badges

6

Use a salted one-way hash [preferably SHA512 using //au2.php.net/manual/en/function.hash.php]... that way, if someone does hack your database, even if they know the salt, they cannot extract the passwords [without a rainbow table, which would be looong for SHA512].

Use HTTPS.

Don't send username/password confirmations via email back to the user when they register.

If you allow cookies for 'remember me' - add an extra login to access administration and profile editing functions.

If a user gets a password wrong, don't say they got the password wrong [say they got the 'username or password wrong' at all times] - that way, less clues on what are valid usernames.

Try and implement screen name versus login - that way, less users will display their login name on user listings.

answered May 3, 2011 at 0:03

HorusKolHorusKol

4,0911 gold badge19 silver badges24 bronze badges

1

  • Never use MD5 or SHA1 hashing algorithms. Always stick to newer ones like SHA512
  • Always use a strong random generated salt
  • Never email your users their passwords, even in case of "Forgot Password"
  • Never use the mysql_* functions. They are long depreciated. Stick to PDO
  • Never store passwords in sessions or cookies

answered May 13, 2013 at 15:51

Here's one bit of advice: make sure your cookies can't be accessed with JS to prevent theft, see Protecting Your Cookies: HttpOnly article by Jeff Atwood

...Through clever construction, the malformed URL just manages to squeak past the sanitizer. The final rendered code, when viewed in the browser, loads and executes a script from that remote server.

...whoever loads this script-injected user profile page has just unwittingly transmitted their browser cookies to an evil remote server!

As we've already established, once someone has your browser cookies for a given website, they essentially have the keys to the kingdom for your identity there...

gnat

21.8k29 gold badges111 silver badges274 bronze badges

answered May 2, 2011 at 16:19

JamesJames

1,82514 silver badges15 bronze badges

How can I secure my login page in PHP?

Getting Started. There are a few steps we need to take before we create our secure login system. ... .
Creating the Login Form Design. ... .
Creating the Database and setting-up Tables. ... .
Authenticating Users with PHP. ... .
Creating the Home Page. ... .
Creating the Profile Page. ... .
Creating the Logout Script..

Is PHP good for security?

PHP is as secure as any other major language. PHP is as secure as any major server-side language. With the new PHP frameworks and tools introduced over the last few years, it is now easier than ever to manage top-notch security.

Which method is secure for securing data in PHP?

SQL Injection By using scripts similar to the above code, attackers can get access to all data tables and sensitive information. The solution to this is to use parameterized SQL queries and PHP Data Objects [PDO]. Using parameterized queries will let the database differentiate between the data and query parts.

What is PHP application security?

Since PHP is so popular, PHP security is essential and the number of vulnerable PHP applications is large. Most PHP web applications share parts of code or scripts with other web applications. If the shared piece of code is found to be vulnerable, all the applications that are using it are also vulnerable.

Chủ Đề