HTML login form return error
I was tasked with cleaning up some bugs on a site my company created a few years ago. I want to preface the code I am posting here with the caveat that I did not write it and I know it is not a very secure login system, but I was assigned a bug fix at hand.
PROBLEM: When users go to login, after they submit the form, the page appears to refresh, requiring their credentials to be re-validated. Registration error is not reported. Until now, I could only duplicate this issue in Firefox and Safari. After successfully logging in, if someone has to log out and log back in, everything works fine. This is right after the initial launch of the browser and trying to log in for the first time. I have duplicated this on other Mac / Windows computers.
Here is a basic HTML login page. I cut off all unnecessary, but can provide more code if needed.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
...
<body>
<form name="login" method="post" id="mainform" action="clogin.php">
<label for="username">Username:</label>
<input type="text" id="username" name="username"><br />
<label for="password">Password:</label>
<input type="password" id="password" name="password"><br />
<input type="submit" name="Submit" class="button" style="float:right;" value="Login">
</form>
</body>
Here is PHP, also trimmed for fat:
<?php
$db = mysql_connect('***', '***', '***') or die("Couldn't connect to the database.");
mysql_select_db('***') or die("Couldn't select the database");
$result = mysql_query("SELECT count(id) FROM merchants WHERE passw='$_POST[password]' AND usern='$_POST[username]'") or die("Couldn't query the user-database.");
$num = mysql_result($result, 0);
if (!$num) {
// When the query didn't return anything,
// display the login form.
$message = "Login Failed: Incorrect username or password";
header('Location: login.php?message='.$message);
} else {
// Start the login session
session_start();
// All output text below this line will be displayed
// to the users that are authenticated. Since no text
// has been output yet, you could also use redirect
// the user to the next page using the header() function.
header('Location: merchants/index.php');
}
Does anyone have an idea where I should start looking? My first thought is that perhaps the form is not actually fully compliant? How can I tell if this is happening? Any hints or pointers would be great. I personally can't seem to find the "code" issue that might be causing this.
a source to share
Resisting the urge to shout "SQL injection attack! 1111" as you say, it rather looks like the form was not submitted correctly.
Some ideas:
Are you checking in any way that the form was submitted in code before querying the database? If so, will this value definitely be sent?
I had this problem in Firefox / Safari before when I had a tag <button type="submit">
to submit a form with no value assigned to that button - IE (<8) was fine with this, but other browsers definitely weren't.
Place the following code on the submit page to see exactly what is being submitted:
die('<pre>'.print_r($_POST,true).'</pre>');
a source to share
What if instead of choosing COUNT(id)
instead, you chose only *
and replaced mysql_result
with mysql_num_rows
, errors still occur?
$result = mysql_query("SELECT * FROM merchants WHERE passw='$_POST[password]' AND usern='$_POST[username]'") or die("Couldn't query the user-database.");
$num = mysql_num_rows($result);
if ($num < 1) {
a source to share
Let's try to rewrite it here and see how it works:
<?php
$db = mysql_connect('***', '***', '***') or die("Couldn't connect to the db.");
mysql_select_db('***') or die("Couldn't select the db");
$result = mysql_query("SELECT id FROM merchants WHERE passw='%s' AND usern='%s'",
mysql_real_escape_string($_POST['username']),
mysql_real_escape_string($_POST['password']))
or die("Couldn't query the user table.");
if (mysql_num_rows($result) != 0) {
$user = mysql_fetch_assoc($result);
$userId = $user['id'];
// Destroy any old session data from before for a fresh session
session_destroy();
session_start();
header('Location: merchants/index.php');
exit();
} else {
$message = "Login Failed: Incorrect username or password";
header('Location: login.php?message='.$message);
exit();
}
?>
Give it a shot. It's always a good idea to throw exit () after you've set the location in the header to make sure no more code is executed.
While you're at it, you might need to set the error message in the sessions array and send it back, rather than via the query string:
...
} else {
$message = "Login Failed: Incorrect username or password";
$_SESSION['login_error'] = $message;
header('Location: login.php');
exit();
}
Then just enter $ _SESSION ['login_message'] on the login page to display any errors.
The id won't make you work, try var_dump () on the $ _POST array to see what's going into your form.
a source to share