CVE-2022-39214: Incorrect Authorization (CWE-863)
value: Combodo iTop is an open source, web-based IT service management platform. Prior to versions 2.7.8 and 3.0.2-1, a user who can log in on iTop is able to take over any account just by knowing the account's username. This issue is fixed in versions 2.7.8 and 3.0.2-1.
CWE description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
CVSS v3 base score: 7.5
Published: 2023-03-14T16:15Z
Repository: https://github.com/Combodo/iTop
Language: PHP
Files changed: application/loginbasic.class.inc.php, application/loginexternal.class.inc.php, application/loginform.class.inc.php, application/loginurl.class.inc.php
Commit date: 2022-09-12 09:45:30 +0200
Commit message: N°5394 - use session for the FSM

Diff: diff --git a/application/loginbasic.class.inc.php b/application/loginbasic.class.inc.php
index 660b45cba8..24b1afb2d1 100644
--- a/application/loginbasic.class.inc.php
+++ b/application/loginbasic.class.inc.php
@@ -57,19 +57,21 @@ class LoginBasic extends AbstractLoginFSMExtension
 			if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $_SESSION['login_mode'], 'internal'))
 			{
 				$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
 				return LoginWebPage::LOGIN_FSM_ERROR;
 			}
+			// Save the checked user
+			$_SESSION['auth_user'] = $sAuthUser;
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
 	protected function OnCredentialsOK(&$iErrorCode)
 	{
 		if ($_SESSION['login_mode'] == 'basic')
 		{
-			list($sAuthUser) = $this->GetAuthUserAndPassword();
+			$sAuthUser = $_SESSION['auth_user'];
 			LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']);
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
diff --git a/application/loginexternal.class.inc.php b/application/loginexternal.class.inc.php
index d4fcb7182a..c2c13de86f 100644
--- a/application/loginexternal.class.inc.php
+++ b/application/loginexternal.class.inc.php
@@ -41,19 +41,21 @@ class LoginExternal extends AbstractLoginFSMExtension
 			if (!UserRights::CheckCredentials($sAuthUser, '', $_SESSION['login_mode'], 'external'))
 			{
 				$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
 				return LoginWebPage::LOGIN_FSM_ERROR;
 			}
+			// Save the checked user
+			$_SESSION['auth_user'] = $sAuthUser;
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
 	protected function OnCredentialsOK(&$iErrorCode)
 	{
 		if ($_SESSION['login_mode'] == 'external')
 		{
-			$sAuthUser = $this->GetAuthUser();
+			$sAuthUser = $_SESSION['auth_user'];
 			LoginWebPage::OnLoginSuccess($sAuthUser, 'external', $_SESSION['login_mode']);
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
diff --git a/application/loginform.class.inc.php b/application/loginform.class.inc.php
index a4fb99db50..9a044fade7 100644
--- a/application/loginform.class.inc.php
+++ b/application/loginform.class.inc.php
@@ -69,10 +69,12 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
 			if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $_SESSION['login_mode'], 'internal'))
 			{
 				$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
 				return LoginWebPage::LOGIN_FSM_ERROR;
 			}
+			// Save the checked user
+			$_SESSION['auth_user'] = $sAuthUser;
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
 	/**
@@ -80,19 +82,11 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
 	 */
 	protected function OnCredentialsOK(&$iErrorCode)
 	{
 		if ($_SESSION['login_mode'] == 'form')
 		{
-			if (isset($_SESSION['auth_user']))
-			{
-				// If FSM reenter this state (example 2FA) then the auth_user is not resubmitted
-				$sAuthUser = $_SESSION['auth_user'];
-			}
-			else
-			{
-				$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
-			}
+			$sAuthUser = $_SESSION['auth_user'];
 			// Store 'auth_user' in session for further use
 			LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']);
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
diff --git a/application/loginurl.class.inc.php b/application/loginurl.class.inc.php
index 8a215e8f5a..166941d31f 100644
--- a/application/loginurl.class.inc.php
+++ b/application/loginurl.class.inc.php
@@ -56,19 +56,21 @@ class LoginURL extends AbstractLoginFSMExtension
 			if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $_SESSION['login_mode'], 'internal'))
 			{
 				$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
 				return LoginWebPage::LOGIN_FSM_ERROR;
 			}
+			// Save the checked user
+			$_SESSION['auth_user'] = $sAuthUser;
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 
 	protected function OnCredentialsOK(&$iErrorCode)
 	{
 		if ($_SESSION['login_mode'] == 'url')
 		{
-			$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
+			$sAuthUser = $_SESSION['auth_user'];
 			LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']);
 		}
 		return LoginWebPage::LOGIN_FSM_CONTINUE;
 	}
 

Vulnerable code: 			list($sAuthUser) = $this->GetAuthUserAndPassword();
			$sAuthUser = $this->GetAuthUser();
			if (isset($_SESSION['auth_user']))
			{
				// If FSM reenter this state (example 2FA) then the auth_user is not resubmitted
				$sAuthUser = $_SESSION['auth_user'];
			}
			else
			{
				$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
			}
			$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
Fixed code: 			// Save the checked user
			$_SESSION['auth_user'] = $sAuthUser;
			$sAuthUser = $_SESSION['auth_user'];
			// Save the checked user
			$_SESSION['auth_user'] = $sAuthUser;
			$sAuthUser = $_SESSION['auth_user'];
			// Save the checked user
			$_SESSION['auth_user'] = $sAuthUser;
			$sAuthUser = $_SESSION['auth_user'];
			// Save the checked user
			$_SESSION['auth_user'] = $sAuthUser;
			$sAuthUser = $_SESSION['auth_user'];