Jump to content

login process fails, but I can't see why


quasiman

Recommended Posts

Hello all,

 

I'm writing a login function and I want to secure the form a bit and so I added a form session hash.  The problem is that it's failing from legitimate login submission because the session doesn't match the token.  I'm sure there's just a simple typo somewhere, but I can't find it.  I included two error sets in the array to let me know what's going on:

    if (isset($_SESSION['$loginToken']))

        $errors['session'] = "Session not set";

    if ($_POST['loginToken'] != $_SESSION['loginToken'])

        $errors['sestoken'] = "loginToken != SessionToken";

 

From this I get the second error, "loginToken != SessionToken".  I check the page source, and the hidden field matches the session and token values that I echo'd out.

 

Here's my two pieces of relevant code:

 

form processing

$errors = array();
$success = array();
$loginToken = md5(uniqid(rand(), true));
$_SESSION['loginToken'] = $loginToken;
echo $_SESSION['loginToken'] . "<br>\n";
echo $loginToken;
if (isset($_POST['loginSubmit']) && $_POST['loginSubmit'] == 'true') {
    $loginEmail = safe($_POST['email']);  //safe = function to sanitize form
    $password = safe($_POST['password']); //safe = function to sanitize form
    if (!filter_var($loginEmail, FILTER_VALIDATE_EMAIL))
        $errors['loginEmail'] = 'Your email address is invalid.';
    if (!isset($_SESSION['loginToken']))
        $errors['session'] = "Session not set";
    if ($_POST['loginToken'] != $_SESSION['loginToken'])
        $errors['sestoken'] = "loginToken != SessionToken";
    if (empty($errors)) {
        $loginPassword = hash('sha256', $loginEmail . $password);
        $query = 'SELECT * FROM users WHERE email = "' . $loginEmail . '" AND password = "' . $loginPassword . '" LIMIT 1';
        $result = mysql_query($query);
        if (mysql_num_rows($result) == 1) {
            $user = mysql_fetch_assoc($result);
            $query = 'UPDATE users SET session_id = "' . session_id() . '" WHERE id = ' . $user['id'] . ' LIMIT 1';
            mysql_query($query);
            header('Location: index.php');
            exit;
        } else {
            $errors['login'] = 'No user was found with the details provided.';
        }
    }
}

 

Login Form

        <form name="loginForm" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, "utf-8"); ?>" method="post">
            
            <h2>Login</h2>
            <?php if ($errors['login']) print '<div class="invalid">' . $errors['login'] . '</div>'; ?>

            <label for="email">Email Address</label>
            <input type="text" name="email" value="<?php echo htmlspecialchars($loginEmail); ?>" />
            <?php if ($errors['loginEmail']) print '<div class="invalid">' . $errors['loginEmail'] . '</div>'; ?>

            <label for="password">Password <span class="info">6-12 chars</span></label>
            <input type="password" name="password" value="" />
            <?php if ($errors['loginPassword']) print '<div class="invalid">' . $errors['loginPassword'] . '</div>'; ?>

            <label for="loginSubmit"> </label>
            <input type="hidden" name="loginSubmit" id="loginSubmit" value="true" />
            <input type="hidden" name="loginToken" value="<?php echo $loginToken; ?>" />
            <input type="submit" value="Login" />
            <?php if ($errors['session']) print '<div class="invalid">' . $errors['session'] . '</div>'; ?>
            <?php if ($errors['sestoken']) print '<div class="invalid">' . $errors['sestoken'] . '</div>'; ?>
        </form>

Link to comment
Share on other sites

Ive read through this quite carefully and like you i can't see any errors, however the script does look a bit awkward in the way of proccessing - maybe try searching the web for a pre-built secure login system, and just modify it to suit your needs - you may even find videos on youtube which you can follow, this way your learning to.

Link to comment
Share on other sites

This is just what I'm seeing after a quick read, and is based on the assumption that the form is processed by submitting to itself, since that's what appears to happen.

 

When the form is generated, the $_SESSION['loginToken'] and the hidden form field loginToken are both assigned their values from $loginToken. That code executes unconditionally, therefore when  the form is submitted that code runs again, generating a new token. Thus, it no longer matches the token that was sent to the browser in the hidden form field, which is now in $_POST['loginToken'].

 

After the form is submitted, if you echo both $_SESSION['loginToken'] and $_POST['loginToken'], my guess is that they won't match.

Link to comment
Share on other sites

As Pikachu stated this is the problematic code:

$loginToken = md5(uniqid(rand(), true));
$_SESSION['loginToken'] = $loginToken;

More specifically, the fact that it runs before checking the POSTed value and the SESSION value. Move it to execute after the check (fails), and after the POST check only, and the script will work as intended.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.