CVE-2022-0414: Improper Validation of Specified Quantity in Input (CWE-1284)
value: Improper Validation of Specified Quantity in Input in Packagist dolibarr/dolibarr prior to 16.0.
CWE description: The product receives input that is expected to specify a quantity (such as size or length), but it does not validate or incorrectly validates that the quantity has the required properties.
CVSS v3 base score: 4.3
Published: 2022-01-31T11:15Z
Repository: https://github.com/dolibarr/dolibarr
Language: PHP
Files changed: htdocs/product/card.php, htdocs/product/class/product.class.php
Commit date: 2022-01-29 15:50:59 +0100
Commit message: Fix #huntr76f3b405-9f5d-44b1-8434-b52b56ee395f
Diff: diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index 420203eedae..64c6b6817bd 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -1868,44 +1868,44 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 			if (!$object->isService()) {
 				if (empty($conf->global->PRODUCT_DISABLE_WEIGHT)) {
 					// Brut Weight
 					print '<tr><td>'.$langs->trans("Weight").'</td><td>';
-					print '<input name="weight" size="5" value="'.$object->weight.'"> ';
-					print $formproduct->selectMeasuringUnits("weight_units", "weight", $object->weight_units, 0, 2);
+					print '<input name="weight" size="5" value="'.(GETPOSTISSET('weight') ? GETPOST('weight') : $object->weight).'"> ';
+					print $formproduct->selectMeasuringUnits("weight_units", "weight", GETPOSTISSET('weight_units') ? GETPOST('weight_units') : $object->weight_units, 0, 2);
 					print '</td></tr>';
 				}
 
 				if (empty($conf->global->PRODUCT_DISABLE_SIZE)) {
 					// Brut Length
 					print '<tr><td>'.$langs->trans("Length").' x '.$langs->trans("Width").' x '.$langs->trans("Height").'</td><td>';
-					print '<input name="size" size="5" value="'.$object->length.'">x';
-					print '<input name="sizewidth" size="5" value="'.$object->width.'">x';
-					print '<input name="sizeheight" size="5" value="'.$object->height.'"> ';
-					print $formproduct->selectMeasuringUnits("size_units", "size", $object->length_units, 0, 2);
+					print '<input name="size" size="5" value="'.(GETPOSTISSET('size') ? GETPOST('size') : $object->length).'">x';
+					print '<input name="sizewidth" size="5" value="'.(GETPOSTISSET('sizewidth') ? GETPOST('sizewidth') : $object->width).'">x';
+					print '<input name="sizeheight" size="5" value="'.(GETPOSTISSET('sizeheight') ? GETPOST('sizeheight') : $object->height).'"> ';
+					print $formproduct->selectMeasuringUnits("size_units", "size", GETPOSTISSET('size_units') ? GETPOST('size_units') : $object->length_units, 0, 2);
 					print '</td></tr>';
 				}
 				if (empty($conf->global->PRODUCT_DISABLE_SURFACE)) {
 					// Brut Surface
 					print '<tr><td>'.$langs->trans("Surface").'</td><td>';
-					print '<input name="surface" size="5" value="'.$object->surface.'"> ';
-					print $formproduct->selectMeasuringUnits("surface_units", "surface", $object->surface_units, 0, 2);
+					print '<input name="surface" size="5" value="'.(GETPOSTISSET('surface') ? GETPOST('surface') : $object->surface).'"> ';
+					print $formproduct->selectMeasuringUnits("surface_units", "surface", GETPOSTISSET('surface_units') ? GETPOST('surface_units') : $object->surface_units, 0, 2);
 					print '</td></tr>';
 				}
 				if (empty($conf->global->PRODUCT_DISABLE_VOLUME)) {
 					// Brut Volume
 					print '<tr><td>'.$langs->trans("Volume").'</td><td>';
-					print '<input name="volume" size="5" value="'.$object->volume.'"> ';
-					print $formproduct->selectMeasuringUnits("volume_units", "volume", $object->volume_units, 0, 2);
+					print '<input name="volume" size="5" value="'.(GETPOSTISSET('volume') ? GETPOST('volume') : $object->volume).'"> ';
+					print $formproduct->selectMeasuringUnits("volume_units", "volume", GETPOSTISSET('volume_units') ? GETPOST('volume_units') : $object->volume_units, 0, 2);
 					print '</td></tr>';
 				}
 
 				if (!empty($conf->global->PRODUCT_ADD_NET_MEASURE)) {
 					// Net Measure
 					print '<tr><td>'.$langs->trans("NetMeasure").'</td><td>';
-					print '<input name="net_measure" size="5" value="'.$object->net_measure.'"> ';
-					print $formproduct->selectMeasuringUnits("net_measure_units", "", $object->net_measure_units, 0, 0);
+					print '<input name="net_measure" size="5" value="'.(GETPOSTISSET('net_measure') ? GETPOST('net_measure') : $object->net_measure).'"> ';
+					print $formproduct->selectMeasuringUnits("net_measure_units", "", GETPOSTISSET('net_measure_units') ? GETPOST('net_measure_units') : $object->net_measure_units, 0, 0);
 					print '</td></tr>';
 				}
 			}
 			// Units
 			if (!empty($conf->global->PRODUCT_USE_UNITS)) {
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 98cff66bf1f..26bf4915d80 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -858,20 +858,31 @@ class Product extends CommonObject
 	 *
 	 * @return int        0 if OK, <0 if KO
 	 */
 	public function verify()
 	{
+		global $langs;
+
 		$this->errors = array();
 
 		$result = 0;
 		$this->ref = trim($this->ref);
 
 		if (!$this->ref) {
 			$this->errors[] = 'ErrorBadRef';
 			$result = -2;
 		}
 
+		$arrayofnonnegativevalue = array('weight'=>'Weight', 'width'=>'Width', 'height'=>'Height', 'length'=>'Length', 'surface'=>'Surface', 'volume'=>'Volume');
+		foreach ($arrayofnonnegativevalue as $key => $value) {
+			if (property_exists($this, $key) && $this->$key < 0) {
+				$langs->load("other");
+				$this->errors[] = $langs->trans("FieldCannotBeNegative", $langs->transnoentitiesnoconv($value));
+				$result = -4;
+			}
+		}
+
 		$rescode = $this->check_barcode($this->barcode, $this->barcode_type_code);
 		if ($rescode) {
 			if ($rescode == -1) {
 				$this->errors[] = 'ErrorBadBarCodeSyntax';
 			} elseif ($rescode == -2) {

Vulnerable code: 					print '<input name="weight" size="5" value="'.$object->weight.'"> ';
					print $formproduct->selectMeasuringUnits("weight_units", "weight", $object->weight_units, 0, 2);
					print '<input name="size" size="5" value="'.$object->length.'">x';
					print '<input name="sizewidth" size="5" value="'.$object->width.'">x';
					print '<input name="sizeheight" size="5" value="'.$object->height.'"> ';
					print $formproduct->selectMeasuringUnits("size_units", "size", $object->length_units, 0, 2);
					print '<input name="surface" size="5" value="'.$object->surface.'"> ';
					print $formproduct->selectMeasuringUnits("surface_units", "surface", $object->surface_units, 0, 2);
					print '<input name="volume" size="5" value="'.$object->volume.'"> ';
					print $formproduct->selectMeasuringUnits("volume_units", "volume", $object->volume_units, 0, 2);
					print '<input name="net_measure" size="5" value="'.$object->net_measure.'"> ';
					print $formproduct->selectMeasuringUnits("net_measure_units", "", $object->net_measure_units, 0, 0);
Fixed code: 					print '<input name="weight" size="5" value="'.(GETPOSTISSET('weight') ? GETPOST('weight') : $object->weight).'"> ';
					print $formproduct->selectMeasuringUnits("weight_units", "weight", GETPOSTISSET('weight_units') ? GETPOST('weight_units') : $object->weight_units, 0, 2);
					print '<input name="size" size="5" value="'.(GETPOSTISSET('size') ? GETPOST('size') : $object->length).'">x';
					print '<input name="sizewidth" size="5" value="'.(GETPOSTISSET('sizewidth') ? GETPOST('sizewidth') : $object->width).'">x';
					print '<input name="sizeheight" size="5" value="'.(GETPOSTISSET('sizeheight') ? GETPOST('sizeheight') : $object->height).'"> ';
					print $formproduct->selectMeasuringUnits("size_units", "size", GETPOSTISSET('size_units') ? GETPOST('size_units') : $object->length_units, 0, 2);
					print '<input name="surface" size="5" value="'.(GETPOSTISSET('surface') ? GETPOST('surface') : $object->surface).'"> ';
					print $formproduct->selectMeasuringUnits("surface_units", "surface", GETPOSTISSET('surface_units') ? GETPOST('surface_units') : $object->surface_units, 0, 2);
					print '<input name="volume" size="5" value="'.(GETPOSTISSET('volume') ? GETPOST('volume') : $object->volume).'"> ';
					print $formproduct->selectMeasuringUnits("volume_units", "volume", GETPOSTISSET('volume_units') ? GETPOST('volume_units') : $object->volume_units, 0, 2);
					print '<input name="net_measure" size="5" value="'.(GETPOSTISSET('net_measure') ? GETPOST('net_measure') : $object->net_measure).'"> ';
					print $formproduct->selectMeasuringUnits("net_measure_units", "", GETPOSTISSET('net_measure_units') ? GETPOST('net_measure_units') : $object->net_measure_units, 0, 0);
		global $langs;

		$arrayofnonnegativevalue = array('weight'=>'Weight', 'width'=>'Width', 'height'=>'Height', 'length'=>'Length', 'surface'=>'Surface', 'volume'=>'Volume');
		foreach ($arrayofnonnegativevalue as $key => $value) {
			if (property_exists($this, $key) && $this->$key < 0) {
				$langs->load("other");
				$this->errors[] = $langs->trans("FieldCannotBeNegative", $langs->transnoentitiesnoconv($value));
				$result = -4;
			}
		}