Login script help. Anything entered as password allows login

Hey Folks,

I just found out (be for anything went live so i am happy) that anything entered into my password field submits as the ‘right’ password weather it is or is not.

Here’s the login script


<?php

session_start();

require_once '../coreLib/config.php';

require_once '../coreLib/clean.class.php';
$clean = new clean;

	$email = $clean->text($_POST['email']);
	$rawPass = $clean->text($_POST['password']);
	$loginquery = "SELECT COUNT(*) AS num_users FROM users WHERE email = :email";

		$valuesquery = array(
				'email' => $email
			);

		try {
			$login = $pdo->prepare($loginquery);
			$login->execute($valuesquery);
		} catch (PDOException $e) {
			$title .= "There was an error :(";
			$output .= "There was an error with pdo/mysql here is the error {$e->getMessage()}";
		}

		$check = $login->fetch(PDO::FETCH_ASSOC);

		if($check['num_users'] == 1){
			$queryselectdetails = "SELECT `hash`,`name`,`password`,`id`,`level`,`farmname` FROM users WHERE email = :email";

			$values = array(
					'email' => $email
				);

		try {
			$getdetails = $pdo->prepare($queryselectdetails);
			$getdetails->execute($values);
		} catch (PDOException $e) {
			$title .= "Errors found!";
			$output .= "There was a pdo/mysql error! Here are the details :: {$e->getMessage()}";
		}

		$details = $getdetails->fetch(PDO::FETCH_ASSOC);
		$password = hash('sha256', $rawPass)."".$details['hash'];
		$unhashed = hash('sha256', $rawPass);

		if($password = $details['password']){
			$_SESSION['name'] = $details['name'];
			$_SESSION['id'] = $details['id'];
			$_SESSION['level'] = $details['level'];
			$_SESSION['farmname'] = $details['farmname'];

			$title .= "Logged in!";
			$output .= "<strong> DBPassword::</strong>" $details['password'];
			$output .= "<strong> Password::</strong> " $password;
			$output .= "<strong> DBHash::</strong> " $details['hash'];
			$output .= "<strong>Has not added::" $unhashed;
			$output .= "You have been logged in as {$_SESSION['name']}";

		}

		else {
			$title .="Wrong Password";
			$output .= "The password you entred was not correct";
		}

}

else{
			$tile .= "User does not exist";
			$output .= "Hello there. We could not locate the email <strong>{$email}</strong> in our database";
		}
?>

Now i only have this section in here

$output .= "<strong> DBPassword::</strong>" $details['password'];
			$output .= "<strong> Password::</strong> " $password;
			$output .= "<strong> DBHash::</strong> " $details['hash'];
			$output .= "<strong>Has not added::" $unhashed;

in hopes it would have helped me de-bug it and see what was going on. But no such luck. So that well be removed as soon as i get this fixed. Everything else is working fine.

Thanks. It must be something i am missing.

if($password = $details['password']){
See the single equal (=) sign? Should be “===”

can also be:

if($password == $details[‘password’]){

Thank you! I know about that, but would never cought it my self!

… but would never cought it my self!

That is a very easy error to make, so you have to recognise it could happen.

These “comparisons” are full of gotchas, any time you fork your code (if/else etc) get used to dumping the variables you are going to be comparing and have a close look at the output.

For example in your code here:


        if($password = $details['password']){ 

Do this temporarily:


// 2 temporary lines of debug
var_dump($password);
var_dump($details['password']);
        if($password = $details['password']){ 

That in itself would not have cured your typo, I am not saying it would. What it would help you focus on is the question “Should I check for sameness of value or should I check for equality before forking my code?”.

You see if you are checking a string “1” against a integer 1 you will get different results depending on whether you check for sameness of value or equality:

Take this example:


$var1 = 1;
$var2 = "1";

if( $var1 == $var2 ) { // use TWO = signs - this one will work
echo "the values are equal";
}

if($var1 === $var2 ) {  // use THREE = signs - this one will not work
echo "the values are equal AND the types are equal";
}

// and here is the proof
var_dump( $var1 ); // integer 1
var_dump( $var2 ); // string (length 1) "1"

When you get accustomed to asking yourself “should this be two or three equal signs?” then making the basic error of only using one will dry up.

… but would never caught it my self!

So work incrementally – always dump your vars when forking code, don’t wait till your code does not work. Do it as you work and remove the lines of debug as you work your way through your script.

PHP Strict and Loose comparison tables

        if($password = $details['password']){

EDIT: will be your problem, as Cups has pointed out.

Also, why are you storing the password twice? Or am i missing something here…the hash… doesnt seem to be doing anything?

The password that is stored in the database is the password with hash added. The hash/salt is stored so i check the hashed password with the salt stored in the database.

But… you’re not using the salt (which i’m assuming is what the ‘hash’ field is in your table.)

    $password = hash('sha256', $rawPass)."".$details['hash'];

That’s not salting a hash, thats… “hash this, then tack this bit on the end.”

You probably meant to take the password, add the ‘salt’ (random string), and THEN hash the whole shebang.