Page 1 of 1
An MD5 login page
Posted: Wed Sep 27, 2006 8:52 am
by impulse()
I'm hoping to create a MySQL table with ID, User & Pass field. I'm able to submit an user registration form that creats a user and hashes their password in the table.
The problem I'm having is comparing a login text box to an entry in a MySQL table. Where would I start with this, am I going to be using mysql_fetch_array?
Regards,
Posted: Wed Sep 27, 2006 9:22 am
by a94060
YOU WOULD start with first getting the password,then doing md5($pass) on it. then you would get the value from the database with select password from users where user=$user.
then,YOU WOULD do
Code: Select all
$result=mysql_fetch_row($query,MYSQL_ASSOC) to get the results,then
if ($password == $result['password']) {
//authorized
}
Posted: Wed Sep 27, 2006 9:30 am
by Mordred
Also it is important to salt the password before hashing it, search the forums for details.
For maximum security (and healthy paranoia), salt with the username AND a salt specified in the code. This makes it harder to calculate rainbow tables (the currently major threat to one-way hashes such as md5) - the attacker will need to read BOTH your SQL data AND your source to be able to calculate tables.
Code: Select all
$sPassword = md5($sFixedSalt.$sUsername.$sPassword); //double-salted for maximum taste
Posted: Wed Sep 27, 2006 10:23 am
by onion2k
As always, I'm going to state for the record that I believe storing passwords as MD5 hashes is a bad idea. Encrypt them instead so you don't have to change them if a user forgets their password.
Posted: Wed Sep 27, 2006 10:31 am
by Mordred
It depends on the size of your userbase I think, but I still find security far more important than a minor difference in user experience in case of a forgotten password. Admin feedback or secret question/answer combo (don't forget to keep them hashed as well) is easy enough to imlpement and to impose on the user. I don't think users will be happy if they realise what it means for the service provider to be able to tell them their password.
Posted: Wed Sep 27, 2006 10:44 am
by ibbo
What good is all this encryption and md5-ing if your user decides to use 123456 as there password?
No matter what efforts you put into been secure your users will always be your achilies heel. Restricting what users can do therefore is of a greater priority than say double salting or md5-ing a double salted encrypted password.
After all a week password cannot be made stronger by encrypting and salting and hashing.
Still good to NOT store them in clear though.
ibbo
Posted: Wed Sep 27, 2006 12:12 pm
by impulse()
Can you let me know where I've gone wrong here. The script runs but without returning any data.
Code: Select all
$user = $_REQUEST["user"];
$pass = $_REQUEST["pass"];
mysql_connect("x", "x", "x");
mysql_select_db("people");
$q = mysql_query("SELECT * from users WHERE user='$user'");
$i = 0;
while ($row = mysql_fetch_array($q)) {
$row['user'] = $user[$i];
$i++;
}
for ($j = 0; $j < 5; $j++) {
echo $row[$j];
}
Posted: Wed Sep 27, 2006 12:24 pm
by Mordred
@ibbo: Agreed, but any measures you take on checking for weak passwords and checking for bruteforce attacks etc. are orthogonal to properly keeping them in the database.
@impulse():
The echo loop is after the last fetch, which means that $row is actually FALSE.
Posted: Wed Sep 27, 2006 1:02 pm
by impulse()
Okay, I've have it working with the following. Sorted. Thanx for the right direction.
Code: Select all
$inputUser = $_REQUEST["username"];
$inputPass = $_REQUEST["password"];
$hashedPassword = md5($inputPass);
mysql_connect("x", "x", "x");
mysql_select_db("people");
$qw = mysql_query("SELECT * from users");
$nr = mysql_numrows($qw) or die ("Error" .mysql_error());
$id = $nr + 1;
if (isset($inputUser)) {
$q = mysql_query("INSERT into users (id, user, pass) VALUES ('$id', '$inputUser', '$hashedPassword')");
}
if (isset($inputUser)) { echo "<h2><br><br>Inserted"; }
The login part
Posted: Wed Sep 27, 2006 1:22 pm
by impulse()
I now have the following which has 2 if statements to determine if the hashed password that was passed from a HTML form is equal to the hashed password in the MySQL DB. The trouble is, if they enter the correct details they receive the message "Good login", but if they enter an incorrect password they also get "Good login". This is only a simple IF statement so I can't see the error here. It is either TRUE or FALSE, it can't be both.
Code: Select all
$user = $_REQUEST["user"];
$pass = $_REQUEST["pass"];
$hashedPass = md5($pass);
mysql_connect("x", "x", "x");
mysql_select_db("people");
$q = mysql_query("SELECT * from users WHERE user='$user'");
$nr = mysql_numrows($q);
while ($i < $nr) {
$usernameFD = mysql_result($q, $i, "user");
$passwordFD = mysql_result($q, $i, "pass");
$i++;
}
if ($hashedPass = $passwordFD) {
echo "Good login";
} else {
echo "Bad login";
}
}
Posted: Wed Sep 27, 2006 1:25 pm
by volka
Make id an auto_increment field and let mysql handle its value.
Create a unique index for the field user so there no two identical usernames can be inserted.
You have to sanitize at least the value of $_REQUEST["username"]; before using it with the sql statement.
Code: Select all
define('MYSQL_DUPLICATE', 1062);
if ( isset($_REQUEST['username'], $_REQUEST['password']) ) {
// you might want to check 'username' and 'password' here for forbidden character, 0-length etc
$db = mysql_connect("x", "x", "x") or die('cannot connect to databse server');
mysql_select_db('people', $db) or die('cannot select database');
$inputUser = mysql_real_escape_string($_REQUEST['username'], $db);
$hashedPassword = mysql_real_escape_string(md5($_REQUEST['password']), $db);
$query = "INSERT INTO users
(`user`, `pass`)
VALUES
('$inputUser', '$hashedPassword')";
$result = mysql_query($query, $db);
if ( MYSQL_DUPLICATE==mysql_errno($db) ) {
die('username already in use');
}
else if ( 0!=mysql_errno($db) ) {
die('sql error '.mysql_errno($db));
}
}
else {
die('username and/or password not set');
}
Posted: Wed Sep 27, 2006 1:29 pm
by Mordred
1. SQL injection with 'user' on both scripts
2. = means assignment, == means value equality check ($hashedPass
== $passwordFD)
3.
Code: Select all
$qw = mysql_query("SELECT * from users");
...
$id = $nr + 1;
...
$q = mysql_query("INSERT into users (id, user, pass) VALUES ('$id', '$inputUser', '$hashedPassword')");
No.
3.1. Declare 'id to be autoincrement.
3.2. Use this INSERT syntax:
Code: Select all
INSERT INTO `users` SET
`user` = '$inputUser',
`pass' = '$hashedPassword'
Posted: Wed Sep 27, 2006 1:48 pm
by impulse()
Thanx for the tips. They're all now in place. Auto_increment is going to very handy for future projects.
Posted: Wed Sep 27, 2006 3:59 pm
by impulse()
OK, I have the full working script as follows but how would it be possible to NOT execute the mysql_query("INSERT"); on the first load of the page. Otherwise I'm getting blank entries written inside of my DB. Would I turn the script into 2 files - A HTML and a PHP where the login part is HTML and then when clicking submit it goes to a PHP page where it runs the mysql_query.
Posted: Wed Sep 27, 2006 4:01 pm
by volka
if ( isset($_REQUEST['username'], $_REQUEST['password']) ) {
// you might want to check 'username' and 'password' here for forbidden character, 0-length etc