CVE-2022-24780: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Combodo iTop is a web based IT Service Management tool. In versions prior to 2.7.6 and 3.0.0, users of the iTop user portal can send TWIG code to the server by forging specific http queries, and execute arbitrary code on the server using http server user privileges. This issue is fixed in versions 2.7.6 and 3.0.0. There are currently no known workarounds.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 8.8
Published: 2022-04-05T19:15Z
Repository: https://github.com/Combodo/iTop
Language: PHP
Files changed: datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
Commit date: 2021-12-10 17:10:46 +0100
Commit message: N°4384 Fix PHP warning when decoding formmanager_data when it is already in a PHP array form

Diff: diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
index 724e68f07f..2e5ae8caf9 100644
--- a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
+++ b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
@@ -77,15 +77,32 @@ class ObjectFormManager extends FormManager
 	protected $aFormProperties;
 	/** @var array $aCallbackUrls */
 	protected $aCallbackUrls = array();
 	/**
 	 * List of hidden fields, used for form update (eg. remove them from the form regarding they dependencies)
+	 *
 	 * @var array $aHiddenFieldsId
 	 * @since 2.7.5
 	 */
 	protected $aHiddenFieldsId = array();
 
+	/**
+	 * @param string|array $formManagerData value of the formmanager_data portal parameter, either JSON or object
+	 *
+	 * @return array formmanager_data as a PHP array
+	 *
+	 * @since 2.7.6 3.0.0 N°4384 method creation : factorize as this is used twice now
+	 */
+	protected static function DecodeFormManagerData($formManagerData)
+	{
+		if (is_array($formManagerData)) {
+			return $formManagerData;
+		}
+
+		return json_decode($formManagerData, true);
+	}
+
 	/**
 	 * @param string $sJson JSON data that must contain at least :
 	 *       - formobject_class : The class of the object that is being edited/viewed
 	 *       - formmode : view|edit|create
 	 *       - values for parent
@@ -99,15 +116,11 @@ class ObjectFormManager extends FormManager
 	 *
 	 * @since 2.7.6 3.0.0 N°4384 new $bTrustContent parameter
 	 */
 	public static function FromJSON($sJson, $bTrustContent = false)
 	{
-		if (is_array($sJson)) {
-			$aJson = $sJson;
-		} else {
-			$aJson = json_decode($sJson, true);
-		}
+		$aJson = static::DecodeFormManagerData($sJson);
 
 		$oConfig = utils::GetConfig();
 		$bIsContentCheckEnabled = $oConfig->GetModuleSetting(PORTAL_ID, 'enable_formmanager_content_check', true);
 		if ($bIsContentCheckEnabled && (false === $bTrustContent)) {
 			/** @noinspection NestedPositiveIfStatementsInspection */
@@ -178,11 +191,11 @@ class ObjectFormManager extends FormManager
 	 *
 	 * @since 2.7.6 3.0.0 N°4384 check formmanager_data
 	 */
 	public static function CanTrustFormLayoutContent($sPostedFormManagerData, $aOriginalFormProperties)
 	{
-		$aPostedFormManagerData = json_decode($sPostedFormManagerData, true);
+		$aPostedFormManagerData = static::DecodeFormManagerData($sPostedFormManagerData);
 		$sPostedFormLayoutType = (isset($aPostedFormManagerData['formproperties']['layout']['type'])) ? $aPostedFormManagerData['formproperties']['layout']['type'] : '';
 
 		if ($sPostedFormLayoutType === 'xhtml') {
 			return true;
 		}

Vulnerable code: 		if (is_array($sJson)) {
			$aJson = $sJson;
		} else {
			$aJson = json_decode($sJson, true);
		}
		$aPostedFormManagerData = json_decode($sPostedFormManagerData, true);
Fixed code: 	 *
	/**
	 * @param string|array $formManagerData value of the formmanager_data portal parameter, either JSON or object
	 *
	 * @return array formmanager_data as a PHP array
	 *
	 * @since 2.7.6 3.0.0 N°4384 method creation : factorize as this is used twice now
	 */
	protected static function DecodeFormManagerData($formManagerData)
	{
		if (is_array($formManagerData)) {
			return $formManagerData;
		}

		return json_decode($formManagerData, true);
	}

		$aJson = static::DecodeFormManagerData($sJson);
		$aPostedFormManagerData = static::DecodeFormManagerData($sPostedFormManagerData);