2
\$\begingroup\$

I am learning from a book, which uses SHA1. I've changed the code to password_hash(), by checking online. Here I query only the password and verify it. I managed get it working, but I feel a bit paranoid about the code. Is the code proper or wrong?

At registration:

//at registration    
$p=mysqli_real_escape_string($dbcon, trim($_POST['psword1']));
$hash =  password_hash($p,PASSWORD_DEFAULT);
//stores $hash in db.

At login:

<?php 
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    //connect to db
    require ('mysqli_connect.php');
    //validate the email
    if (!empty($_POST['email'])){
       $e = mysqli_real_escape_string($dbcon, $_POST['email']);
       }else {
       $e = FALSE;
       echo '<p class="error"> You forgot to enter your email.</p>';
    }
// validate the password
if (!empty($_POST['psword'])){
      $p=mysqli_real_escape_string($dbcon,$_POST['psword']);
   } else {
       $p = FALSE;
       echo '<p class="error">You forgot to enter your password.</p>';
     }
      if (!empty($e && $p )){
        //get email info
             $sql = "SELECT  psword FROM users WHERE email = '$e'  LIMIT 1";
             $query = mysqli_query($dbcon,$sql);
             $row = mysqli_fetch_row($query);
             $dbpassword=$row[0];


        //run if email and password got value
        if (password_verify($p,$dbpassword)){ 
          // Retrieve the user_id, first_name 
          $q = "SELECT user_id, fname, user_level,lname,registration_date FROM users WHERE (email='$e')";
          // Run the query and assign it to the variable $result
          $result = mysqli_query ($dbcon, $q);
          // Count the number of rows that match the email/password combination
          if (@mysqli_num_rows($result) == 1) {//if one database row (record) matches
            // Start the session, fetch the record and insert the three values in an array
            session_start(); 
            $_SESSION = mysqli_fetch_array ($result, MYSQLI_ASSOC);
            // Ensure that the user level is an integer.
            $_SESSION['user_level'] = (int) $_SESSION['user_level'];
            // Use a ternary operation to set the URL
            $url = ($_SESSION['user_level'] === 1) ? 'index.php' : 'members.php';
            header('Location: ' . $url); // Make the browser load either the members’ or the admin page
            exit(); // Cancel the rest of the script
            mysqli_free_result($result);
            mysqli_close($dbcon);
        } else { // No match was made.
            echo '<p class="error">The e-mail address and password entered do not match our records <br>Perhaps you need to register, just click the Register button on the header menu</p>';
          }
          } else { // If there was a problem.
            echo '<p class="error">Please try again.</p>';
            }

   }
mysqli_close($dbcon);
}
?>
\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

PLEASE do not do anything to the password prior to hashing it. Do not escape it. Do not trim() it. Just pass it directly to password_hash.

Secondly, you never fetch the hash from the database. That looks weird that you have a magic $dbpassword variable...

Third: Please use prepared statements. Escaping can be secure, but prepared statements are so much easier to verify and work with.

Fourth: Don't close the connection all over the place like that. Let it get closed for you by the script end, that way you don't need to reconnect multiple times in the same script.

Fifth: Please use consistent indentation. It will make your life a LOT easier.

\$\endgroup\$
4
  • \$\begingroup\$ oops. that was the important part i want to ask. i have updated. please check. Thanks. I will follow your advice. 5th: i didn't use indentation. earlier someone told, so i just put some spaces. i will take care of it. \$\endgroup\$ Feb 5, 2015 at 16:16
  • \$\begingroup\$ Proper indentation is the single most important thing you can do to clean up your code and make it easier to write and debug. \$\endgroup\$
    – ircmaxell
    Feb 5, 2015 at 16:42
  • \$\begingroup\$ Sure i will do. \$\endgroup\$ Feb 5, 2015 at 16:49
  • 1
    \$\begingroup\$ @ircmaxell Following a Q&A on Stack the other day for something somewhat similar, I had my suspicions as to what to do for a recent script I wrote in regards to the use of trim() for all inputs (this including the password) and a prepared statement along with the password_hash() function. When in doubt, I "Google" and found this Q&A that answered everything for me. I'd like to say "thanks" for your long lasting and worthy/informative contributions here. I just thought I'd mention that, cheers. \$\endgroup\$ Apr 8, 2016 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.