VYPR
High severityNVD Advisory· Published Aug 21, 2022· Updated Aug 3, 2024

Exposure of Private Personal Information to an Unauthorized Actor in notrinos/notrinoserp

CVE-2022-2921

Description

Exposure of Private Personal Information to an Unauthorized Actor in GitHub repository notrinos/notrinoserp prior to v0.7. This results in privilege escalation to a system administrator account. An attacker can gain access to protected functionality such as create/update companies, install/update languages, install/activate extensions, install/activate themes and other permissive actions.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
notrinos/notrinos-erpPackagist
< 0.70.7

Affected products

1

Patches

1
1b9903f4deea

changed password hash method from md5 to bcrypt.

https://github.com/notrinos/notrinoserpnotrinosAug 21, 2022via ghsa
5 files changed · +33 16
  • admin/change_current_user_password.php+3 3 modified
    @@ -25,7 +25,7 @@ function can_process() {
     	$Auth_Result = hook_authenticate($_SESSION['wa_current_user']->username, $_POST['cur_password']);
     
     	if (!isset($Auth_Result))	// if not used external login: standard method
    -		$Auth_Result = get_user_auth($_SESSION['wa_current_user']->username, md5($_POST['cur_password']));
    +		$Auth_Result = authenticate_user($_SESSION['wa_current_user']->username, $_POST['cur_password']);
     
     	if (!$Auth_Result) {
     		display_error( _('Invalid password entered.'));
    @@ -57,7 +57,7 @@ function can_process() {
     		if ($SysPrefs->allow_demo_mode)
     			display_warning(_('Password cannot be changed in demo mode.'));
     		else {
    -			update_user_password($_SESSION['wa_current_user']->user, $_SESSION['wa_current_user']->username, md5($_POST['password']));
    +			update_user_password($_SESSION['wa_current_user']->user, $_SESSION['wa_current_user']->username, password_hash($_POST['password'], PASSWORD_DEFAULT));
     			display_notification(_('Your password has been updated.'));
     		}
     		$Ajax->activate('_page_body');
    @@ -86,4 +86,4 @@ function can_process() {
     
     submit_center( 'UPDATE_ITEM', _('Change password'), true, '',  'default');
     end_form();
    -end_page();
    \ No newline at end of file
    +end_page();
    
  • admin/create_coy.php+4 4 modified
    @@ -20,7 +20,7 @@
     
     page(_($help_context = 'Create/Update Company'));
     
    -$comp_subdirs = array('images', 'pdf_files', 'backup','js_cache', 'reporting', 'attachments');
    +$comp_subdirs = array('images', 'pdf_files', 'backup', 'js_cache', 'reporting', 'attachments');
     
     simple_page_mode(true);
     /*
    @@ -107,7 +107,7 @@ function handle_submit($selected_id) {
     
     		$conn = $db_connections[$selected_id];
     		if (($db = db_create_db($conn)) === false) {
    -			display_error(_('Error creating Database: ') . $conn['dbname'] . _(', Please create it manually'));
    +			display_error(_('Error creating Database: ').$conn['dbname']._(', Please create it manually'));
     			$error = true;
     		}
     		else {
    @@ -120,7 +120,7 @@ function handle_submit($selected_id) {
     			else {
     				if (!isset($_POST['admpassword']) || $_POST['admpassword'] == '')
     					$_POST['admpassword'] = 'password';
    -				update_admin_password($conn, md5($_POST['admpassword']));
    +				update_admin_password($conn, password_hash($_POST['admpassword']), PASSWORD_DEFAULT);
     			}
     		}
     		if ($error) {
    @@ -350,4 +350,4 @@ function display_company_edit($selected_id) {
     
     end_form();
     
    -end_page();
    \ No newline at end of file
    +end_page();
    
  • admin/db/users_db.inc+21 4 modified
    @@ -112,12 +112,29 @@ function delete_user($id) {
     
     //-----------------------------------------------------------------------------------------------
     
    -function get_user_auth($user_id, $password) {
    +function authenticate_user($user_id, $password) {
     
    -	$sql = "SELECT * FROM ".TB_PREF."users WHERE user_id = ".db_escape($user_id)." AND"
    -		." password=".db_escape($password);
    +	$sql1 = "SELECT password FROM ".TB_PREF."users WHERE user_id = ".db_escape($user_id);
     
    -	return db_num_rows(db_query($sql, 'could not get validate user login for '.$user_id)) != 0;
    +	$result = db_query($sql1, 'could not get user login for '.$user_id);
    +
    +	if(db_num_rows($result) == 0)
    +		return false;
    +
    +	$hash = db_fetch($result)[0];
    +
    +	// The user's password hash may have been created long ago by md5 password algorithm on the old NotrinosERP versions
    +	if(password_verify($password, $hash) || $hash == md5($password)) {
    +		if(password_needs_rehash($hash, PASSWORD_DEFAULT) === true) {
    +			$new_hash = password_hash($password, PASSWORD_DEFAULT);
    +			$sql2 = "UPDATE ".TB_PREF."users SET password = ".db_escape($new_hash)." WHERE user_id = ".db_escape($user_id);
    +			db_query($sql2, 'could not update password hash for '.$user_id);
    +		}
    +
    +		return true;
    +	}
    +
    +	return false;
     }
     
     //-----------------------------------------------------------------------------------------------
    
  • admin/users.php+2 2 modified
    @@ -56,12 +56,12 @@ function can_process($new) {
     			update_user_prefs($selected_id, get_post(array('user_id', 'real_name', 'phone', 'email', 'role_id', 'language', 'print_profile', 'rep_popup' => 0, 'pos')));
     
     			if ($_POST['password'] != '')
    -				update_user_password($selected_id, $_POST['user_id'], md5($_POST['password']));
    +				update_user_password($selected_id, $_POST['user_id'], password_hash($_POST['password'], PASSWORD_DEFAULT));
     
     			display_notification_centered(_('The selected user has been updated.'));
     		} 
     		else {
    -			add_user($_POST['user_id'], $_POST['real_name'], md5($_POST['password']), $_POST['phone'], $_POST['email'], $_POST['role_id'], $_POST['language'], $_POST['print_profile'], check_value('rep_popup'), $_POST['pos']);
    +			add_user($_POST['user_id'], $_POST['real_name'], password_hash($_POST['password'], PASSWORD_DEFAULT), $_POST['phone'], $_POST['email'], $_POST['role_id'], $_POST['language'], $_POST['print_profile'], check_value('rep_popup'), $_POST['pos']);
     			$id = db_insert_id();
     			// use current user display preferences as start point for new user
     			$prefs = $_SESSION['wa_current_user']->prefs->get_all();
    
  • includes/current_user.inc+3 3 modified
    @@ -69,11 +69,11 @@ class current_user {
     
     		// Use external authentication source if any.
     		// Keep in mind you need to have user data set for $loginname
    -		// in FA users table anyway to successfully log in.
    +		// in NotrinosERP users table anyway to successfully log in.
     		$Auth_Result = hook_authenticate($loginname, $password);
     
     		if (!isset($Auth_Result))	// if not used: standard method
    -			$Auth_Result = get_user_auth($loginname, md5($password));
    +			$Auth_Result = authenticate_user($loginname, $password);
     		if ($SysPrefs->login_delay > 0)
     			write_login_filelog($loginname, $Auth_Result);
     		if ($Auth_Result) {
    @@ -151,7 +151,7 @@ class current_user {
     		if ($user != false) {
     
     			$password = generate_password();
    -			$hash = md5($password);
    +			$hash = password_hash($password);
     
     			update_user_password($user['id'], $user['user_id'], $hash);
     			
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.