security: Use more secure password hashes (#8213)

* More secure password hashes
Use PHP 5.5 password_hash(), currently uses bcrypt
increase password field length as per php documentation

* Use password_hash()/password_verify() for cookies too

* forgot to update db_schema.yaml
This commit is contained in:
Tony Murray
2018-02-08 17:08:21 -06:00
committed by Neil Lathwood
parent 496575ea99
commit 1188b53192
5 changed files with 42 additions and 54 deletions

View File

@ -27,7 +27,6 @@ namespace LibreNMS\Authentication;
use LibreNMS\Config;
use LibreNMS\Interfaces\Authentication\Authorizer;
use LibreNMS\Exceptions\AuthenticationException;
use Phpass\PasswordHash;
abstract class AuthorizerBase implements Authorizer
{
@ -138,8 +137,7 @@ abstract class AuthorizerBase implements Authorizer
} else {
$token = strgen();
$auth = strgen();
$hasher = new PasswordHash(8, false);
$token_id = $_SESSION['username'] . '|' . $hasher->HashPassword($_SESSION['username'] . $token);
$token_id = $_SESSION['username'] . '|' . password_hash($_SESSION['username'] . $token, PASSWORD_DEFAULT);
$db_entry['session_username'] = $_SESSION['username'];
$db_entry['session_token'] = $token;
@ -169,8 +167,7 @@ abstract class AuthorizerBase implements Authorizer
array($uname, $sess_id)
);
$hasher = new PasswordHash(8, false);
if ($hasher->CheckPassword($uname . $session['session_token'], $hash)) {
if (password_verify($uname . $session['session_token'], $hash)) {
$_SESSION['username'] = $uname;
return true;
}

View File

@ -13,41 +13,41 @@ class MysqlAuthorizer extends AuthorizerBase
public function authenticate($username, $password)
{
$encrypted_old = md5($password);
$row = dbFetchRow('SELECT username,password FROM `users` WHERE `username`= ?', array($username));
if ($row['username'] && $row['username'] == $username) {
// Migrate from old, unhashed password
if ($row['password'] == $encrypted_old) {
$row_type = dbFetchRow('DESCRIBE users password');
if ($row_type['Type'] == 'varchar(34)') {
$this->changePassword($username, $password);
}
$hash = dbFetchCell('SELECT `password` FROM `users` WHERE `username`= ?', array($username));
return true;
} elseif (substr($row['password'], 0, 3) == '$1$') {
$row_type = dbFetchRow('DESCRIBE users password');
if ($row_type['Type'] == 'varchar(60)') {
if ($row['password'] == crypt($password, $row['password'])) {
$this->changePassword($username, $password);
}
}
}
$hasher = new PasswordHash(8, false);
if ($hasher->CheckPassword($password, $row['password'])) {
// check for old passwords
if (strlen($hash) == 32) {
// md5
if (md5($password) === $hash) {
$this->changePassword($username, $password);
return true;
}
}//end if
} elseif (starts_with($hash, '$1$')) {
// old md5 crypt
if (crypt($password, $hash) == $hash) {
$this->changePassword($username, $password);
return true;
}
} elseif (starts_with($hash, '$P$')) {
// Phpass
$hasher = new PasswordHash();
if ($hasher->CheckPassword($password, $hash)) {
$this->changePassword($username, $password);
return true;
}
}
if (password_verify($password, $hash)) {
return true;
}
throw new AuthenticationException();
}//end authenticate()
}
public function reauthenticate($sess_id, $token)
{
return $this->checkRememberMe($sess_id, $token);
}//end reauthenticate()
}
public function canUpdatePasswords($username = '')
{
@ -72,17 +72,15 @@ class MysqlAuthorizer extends AuthorizerBase
return 0;
}
$hasher = new PasswordHash(8, false);
$encrypted = $hasher->HashPassword($password);
$encrypted = password_hash($password, PASSWORD_DEFAULT);
return dbUpdate(array('password' => $encrypted), 'users', '`username` = ?', array($username));
}//end changepassword()
}
public function addUser($username, $password, $level = 0, $email = '', $realname = '', $can_modify_passwd = 1, $description = '')
{
if (!$this->userExists($username)) {
$hasher = new PasswordHash(8, false);
$encrypted = $hasher->HashPassword($password);
$userid = dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname, 'can_modify_passwd' => $can_modify_passwd, 'descr' => $description), 'users');
$encrypted = password_hash($password, PASSWORD_DEFAULT);
$userid = dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname, 'can_modify_passwd' => $can_modify_passwd, 'descr' => $description), 'users');
if ($userid == false) {
return false;
} else {
@ -94,8 +92,7 @@ class MysqlAuthorizer extends AuthorizerBase
} else {
return false;
}
}//end adduser()
}
public function userExists($username, $throw_exception = false)
{
@ -105,14 +102,12 @@ class MysqlAuthorizer extends AuthorizerBase
public function getUserlevel($username)
{
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username));
}//end getUserlevel()
}
public function getUserid($username)
{
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username));
}//end getUserid()
}
public function deleteUser($userid)
{
@ -123,23 +118,20 @@ class MysqlAuthorizer extends AuthorizerBase
dbDelete('users', '`user_id` = ?', array($userid));
return dbDelete('users', '`user_id` = ?', array($userid));
}//end deluser()
}
public function getUserlist()
{
return dbFetchRows('SELECT * FROM `users` ORDER BY `username`');
}//end getUserlist()
}
public function getUser($user_id)
{
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id));
}//end getUser()
}
public function updateUser($user_id, $realname, $level, $can_modify_passwd, $email)
{
dbUpdate(array('realname' => $realname, 'level' => $level, 'can_modify_passwd' => $can_modify_passwd, 'email' => $email), 'users', '`user_id` = ?', array($user_id));
}//end updateUser()
}
}

View File

@ -1545,7 +1545,7 @@ users:
Columns:
- { Field: user_id, Type: int(11), 'Null': false, Extra: auto_increment }
- { Field: username, Type: varchar(255), 'Null': false, Extra: '' }
- { Field: password, Type: varchar(60), 'Null': true, Extra: '' }
- { Field: password, Type: varchar(255), 'Null': true, Extra: '' }
- { Field: realname, Type: varchar(64), 'Null': false, Extra: '' }
- { Field: email, Type: varchar(64), 'Null': false, Extra: '' }
- { Field: descr, Type: char(30), 'Null': false, Extra: '' }

View File

@ -2,7 +2,6 @@
<?php
use LibreNMS\Authentication\Auth;
use Phpass\PasswordHash;
$options = getopt('u:rdvh');
if (isset($options['h']) || !isset($options['u'])) {
@ -96,8 +95,7 @@ try {
exit;
}
$hasher = new PasswordHash(8, false);
$token = $session['session_username'] . '|' . $hasher->HashPassword($session['session_username'] . $session['session_token']);
$token = $session['session_username'] . '|' . password_hash($session['session_username'] . $session['session_token'], PASSWORD_DEFAULT);
$auth = $authorizer->reauthenticate($session['session_value'], $token);
if ($auth) {

1
sql-schema/235.sql Normal file
View File

@ -0,0 +1 @@
ALTER TABLE users MODIFY password VARCHAR(255);