Need some help with login system

mysqli_real_escape_string must be used for the every data value which you enclose in quotes in the query.

ahh I wasn’t using it in cookiecheck.php, fixed that. thanks :slight_smile: I don’t see that I am putting plain password in the cookie though since it is $safemix

will test this all now to make sure it works

well it seems to be working just fine. FINALLY. :slight_smile:

I am going about this remember-me feature the right way, yes?

  1. upon login, set cookies + session.
  2. upon return to site, check for cookies, if they exist, verify and re-set session.

that’s how you’re supposed to do it?

also, should I maybe set cookies again in 2), so whenever the user returns to the site the cookies expiry date is refreshed? like this:


<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/connect.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/functions.php';
if (isset($_COOKIE['c_username']) && isset($_COOKIE['c_password'])) {
	$cookie_u = $_COOKIE['c_username'];
	$cookie_p = $_COOKIE['c_password'];
	$safe_u = safe($link, $cookie_u);
	$safe_p = safe($link, $cookie_p);
	$check = mysqli_query($link, "SELECT username, password FROM members WHERE username = '$safe_u' AND password = '$safe_p'");
	$result = mysqli_num_rows($check);
	if ($result != 1)
		{
		include 'login.php';
		}
	else
		{
		$_SESSION['username'] = $safe_u;
        // added the following 2 lines
        setcookie("c_username", $username, time()+3600*24*365, "/", ".mysite.com");
		setcookie("c_password", $safemix, time()+3600*24*365, "/", ".mysite.com");
		include 'main.php';
		}
	}
else
	include 'login.php';
	?>

will that work to reset the timer on the cookie, or should I not setcookie like that again when the cookies are already there? kinda worried that’s gonna mess my scripts up since it’s working fine right now. hehe

also, I am having an issue that http://www.mysite.com/ is working as a session, but if I go to http://mysite.com/ it starts a new session… what am I doing wrong?

Why would you use MD5, though? It’s been effectively broken for 15 years, now. Sure, it’s not yet completely trivial to collide an arbitrary hash (takes a couple hours on modern hardware), but give it a few years. Do you want to have to explain to your clients why you need to go back and update their site due to a security vulnerability which was discovered a decade and a half before your created their site?

To the OP: change your MD5 hash to something a bit more secure (SHA-256 at a minimum, or my preference: whirlpool). Additionally, you should be randomly generating a salt and appending that to the password, then storing the salt in the database.

Also, you should be hashing the password a few thousand times for additional security (see http://en.wikipedia.org/wiki/Key_strengthening for details).

Ultimately, what this really means is that if you’re a bit newish to PHP, or uncomfortable with the security aspects, you probably shouldn’t write your own login function. There are far too many things you could be doing wrong.

But how can one become seasoned to PHP without own experience?

Even if it becomes trivial to generate a collision this is not the same as generating a collision for a specific hash. But even if that became trivial it does not apply in this case.

All you are doing here is storing a random 128 bit hash in the cookie and checking it against your db record. Unless the attacker knows how you generated this and can reproduce it there is no problem. You can’t brute force this in any remotely feasible time, so md5ing a bunch of random data to generate a key is fine.

If I’m wrong please correct me. But tell me why instead of “md5 is broken”.

There’s nothing wrong with gaining experience. There is something wrong with attempting to pass off a production-level authentication mechanism as secure when it’s very obviously not.

I’m not saying that the OP is attempting to commit fraud, but security is hard. You don’t make the first thing that you do while learning math Integral Calculus. Why make one of the first things you do in PHP writing auth systems? Why not let people with more experience handle that one for your first projects?

The problem with your post is that it has been possible to trivially find a collision for an arbitrary message using MD5 for five years now (see http://cryptography.hyperlink.cz/md5/MD5_collisions.pdf – that group was able to find a collision for an arbitrary MD5 hash in eight hours using a 1.6GHz processor…in 2005). There are two places as I understand it, that our OP is going to use a hash: the first is in the password storage, and the second is in a “Remember me” function.

The “Remember” function doesn’t need a hash. There’s no reason to use a hash: just use a sufficiently lengthy randomly generated key which you store in the cookie. Because the key is random, and there’s no actual meaning to it (it’s useless outside of that website), there’s no reason to hash it. In this case hashing (due to the possibility of collisions in the domain) are actually less secure than simply using the key.

Passwords on the other hand, are secrets. They (by design) should only be known by the person who created the password. As such, well-designed systems are put together to be able to check the user’s password without actually knowing the password in a human-readable format for more than the time it takes for the computer to transform it. This is why we use hashing – it’s designed to provide one-way encryption and “fingerprint” the object in question.

Salting the password and using multiple rounds of encryption (with the password appended) goes a long way to make things more secure, but MD5 has been known to be insecure since 1995. It may not have been insecure for all practical applications for that whole time, but implementing another algorithm is trivial. The difference between implementing Whirlpool and implementing MD5 in your system is six characters. The difference between compromising MD5 and compromising Whirlpool is a couple of thousand years. Why wouldn’t you use the slower, more secure, proven algorithm?

I see both sides of the story here - MD5 is technically “broken” because in a list of strings and their hashes, every so often you’ll find a duplicate hash.

However, this list needs to be huge. I’m talking massive - 2000 is a slight underestimate. Raise it to the nth power and you’d be closer ;). The MAJOR thing here is that if someone has access to your database to see this MD5 in the first place, you have A LOT more problems than them finding your site’s Admin password.

The recommendation would be to salt the password and then encrypt it with an algorithm - SHA, MD5, whirlpool - the choice is yours. However, you cannot make an informed decision until you look at, and understand, the algorithms behind each and know the weaknesses. If you have that kind of understanding of each, and not just take in what you’ve heard from not-so-explanitory articles, you will find out that no algorithm is perfect.

But guys, can we please keep this thread on topic? Sure, encryption is relevant to login systems, but arguing over what encryption to use is only going to confuse the original poster. I’m going to see if we can get this thread split into the OP’s thread and the encryption thread. Until then, please keep on track.

Note also that if you want a good debate about this, both sides need good backup data so we can have a reliable thread summary. Half of the debate so far has resulted in pure insult to either side which contributes nothing to these forums. The winner of an argument is the one who supplies real-life information, backs it up (the source code behind testing would be useful) and explains the results - not the person who resorts to derogatory comments to others.

Jake – I don’t think the majority of your post there applies specifically to me, but I think the OP has already been given the advice necessary: “Don’t do it yourself”. There are a number of options out there for authentication, PEAR has a couple which look promising (http://pear.php.net/search.php?q=authentication&in=packages), or you could do a quick google search and find a great deal more.

The point I’ve been repeatedly trying to stress to the OP is that security is hard, and by trying to do things yourself, you just end up being another in the long line of PHP applications which manage to do something with Authentication wrong. It’s telling that in Windows 2000, even Microsoft moved away from an in-house Authentication framework, adopting Kerberos. If you don’t know, and you’re not willing to put in the weeks it takes to research how to do this effectively, you just shouldn’t do it. Let someone who has already done that legwork for you, and developed an extensible authentication framework in your stead, handle the heavy lifting.

That’s not a problem with the post, it’s the whole point. The message is not known, so it doesn’t matter how easy it is to generate a collision for a known message.

Neither the token or the password are vulnerable to collision attacks. Collision attacks are where one (malicious) message is able to pass itself off as another (trusted) message via an identical hash. In this case the attacker does not know the message or it’s hash.

Which still doesn’t answer the question of why you would choose to use MD5. What is the purpose of making a choice like that?

I wasn’t trying to answer that question, just clear up why md5 isn’t broken if you just want a quick token or two.
Out of interest:

grep -r "md5(" ./symfony

Found 71 lines including this

./lib/vendor/symfony/lib/form/sfForm.class.php:        self::$CSRFSecret = md5(__FILE__.php_uname());
./lib/vendor/symfony/lib/form/sfForm.class.php:    return md5($secret.session_id().get_class($this));