PHP password storage in MariaDB

Years ago I built a site that had login and account creation capability using SHA1 and MySQL. In preparation for a new webiste I loaded the old site into a droplet it still works fine. At the time SHA1 and simple input sanitizing was fine, but since then SHA1 has been cracked and PDO is recommended for sanitizing database values.

The original code looked like this:


// Read the data from the form
$userlogin = htmlspecialchars($_POST['login']);
$password  = htmlspecialchars($_POST['password'];
// The hash stored in the database.
$passwdHash = sha1($Password);

// Verification
$userlogin = htmlspecialchars($_POST['login']);
$password  = htmlspecialchars$_POST['password'];
$passwdHash = sha1($password);
$sql = "SELECT *
FROM users
WHERE username = '$login' && password = '$passwdHash' ";

Without really thinking about it, I sanitized the password input with htmlspecialchars and in both storing and retrieving the password it didn’t have any impact.

I basically copied the code into my new project and then changed SHA1 to password_hash. That didn’t work because the password_hash requires password_verify to check the hash when you retrieve it from the database. That worked when I tested the login code by copying and pasting the login info from php_error.log –> error_log(login: $userlogin  hash: $hash) into the users table. It didn’t work when I created a signup page and entered the data automatically. The reason is that sanitizing the password with htmlspecialchars changes it somehow. This is what I do instead. Note that it doesn’t matter what the user enters in the password field because the hash function transforms it into a 60 character hash so there is no need to sanitize.


// Read the data from the form
// Sanitized passord is used in javascript just for checking that a password was entered
$Password = htmlspecialchars($_POST["Password"]); 
$UserLogin = htmlspecialchars($_POST["UserLogin"]);
$PasswdHash = password_hash($_POST["Password"], PASSWORD_DEFAULT);

// Enter into the database with PDO
$sql = "INSERT INTO `Database`.`users` (`user_login`, `user_pass`,
$sql .=  "VALUES (:user_login, user_pass, ...

$stmt->bindParam(': user_login', $UserLogin);
$stmt->bindParam(':user_pass',   $PasswdHash);
...

// Validate the password. Retrieve by user_login only. 
// Don’t do anything to the password that was entered by the user.

foreach($result as $row) {
  $user_login  = $row['user_login'];
  $hash = $row['user_pass'];

  if ( password_verify($_POST['password'], $hash) ) {
    $_SESSION['userID']    = $row['ID'];
    $_SESSION['userName']   = $row['user_name'];
    $_SESSION['userDisplayName'] = $row['display_name'];
    $passwordIsValid = TRUE;
  }

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.