CVE-2022-2714: Improper Handling of Length Parameter Inconsistency (CWE-130)
value: Improper Handling of Length Parameter Inconsistency in GitHub repository francoisjacquet/rosariosis prior to 10.0.
CWE description: The product parses a formatted message or structure, but it does not handle or incorrectly handles a length field that is inconsistent with the actual length of the associated data.
CVSS v3 base score: 9.8
Published: 2022-09-06T11:15Z
Repository: https://github.com/francoisjacquet/rosariosis
Language: PHP
Files changed: CHANGES.md, Warehouse.php
Commit date: 2022-08-05 18:05:23 +0200
Commit message: Limit $_POST array size to a maximum of 16MB

Diff: diff --git a/CHANGES.md b/CHANGES.md
index f8520c5d5..1975576da 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -92,10 +92,11 @@ Changes in 10.0
 - $DatabasePort configuration variable is now optional in config.inc.sample.php, INSTALL.md, INSTALL_es.md & INSTALL_fr.md
 - SQL start staff_fields ID sequence at 200000000 for coherence with custom_fields in rosariosis.sql & Fields.fnc.php
 - MySQL use LONGTEXT type for textarea field in Fields.fnc.php & DisciplineForm.php
 - SQL Check requested assignment belongs to teacher in Assignments.php
 - CSS fix responsive when really long string with no space in stylesheet.css
+- Limit `$_POST` array size to a maximum of 16MB in Warehouse.php
 
 Changes in 9.3.1
 ----------------
 - Fix regression since 2.9 Schedule multiple courses in plugins/Moodle/Scheduling/MassSchedule.php
 - Fix SQL to select Periods where exists CP in TeacherCompletion.php & Administration.php
diff --git a/Warehouse.php b/Warehouse.php
index d7c743152..cd2987961 100644
--- a/Warehouse.php
+++ b/Warehouse.php
@@ -284,10 +284,54 @@ function array_rwalk( &$array, $function )
 			unset( $array[$key[$i]] );
 		}
 	}
 }
 
+/**
+ * Limit $_POST array size to a maximum of 16MB
+ *
+ * $_POST array size is limited by PHP post_max_size configuration option
+ * But this includes $_FILES as well & post_max_size must be greater than upload_max_filesize
+ * One may want to be able to upload a 100MB file, but may not want the $_POST var,
+ * with for example the text or HTML of a textarea to be 100MB and later stored in database.
+ */
+if ( ! defined( 'ROSARIO_POST_MAX_SIZE_LIMIT' ) )
+{
+	/**
+	 * Fix a limit of 16MB based on MySQL max_allowed_packet default limit
+	 * Limit size can be overriden in the config.inc.php file
+	 */
+	define( 'ROSARIO_POST_MAX_SIZE_LIMIT', 16 * 1024 * 1024 ); // 16MB in bytes.
+}
+
+if ( $_POST
+	&& strlen( serialize( $_POST ) ) > ROSARIO_POST_MAX_SIZE_LIMIT )
+{
+	$post_max_size_limit = function( $value ) {
+		if ( strlen( $value ) > ( ROSARIO_POST_MAX_SIZE_LIMIT / 4 ) )
+		{
+			// Reset value > limit / 4, or else we would send it in the HackingLog email!
+			return 'ROSARIO_POST_MAX_SIZE_LIMIT / 4 reached.';
+		}
+
+		return $value;
+	};
+
+	array_rwalk( $_POST, $post_max_size_limit );
+
+	array_rwalk( $_REQUEST, $post_max_size_limit );
+
+	require_once 'ProgramFunctions/HackingLog.fnc.php';
+
+	// Do not translate.
+	$error[] = 'You are submitting too much data: over the ' .
+		( ROSARIO_POST_MAX_SIZE_LIMIT / 1024 / 1024 ) .
+		'M limit. Try reducing the data you are submitting.';
+
+	HackingLog();
+}
+
 /**
  * Sanitize $_REQUEST array
  * ($_POST + $_GET)
  */
 // Escape strings for DB queries.

Fixed code: - Limit `$_POST` array size to a maximum of 16MB in Warehouse.php
/**
 * Limit $_POST array size to a maximum of 16MB
 *
 * $_POST array size is limited by PHP post_max_size configuration option
 * But this includes $_FILES as well & post_max_size must be greater than upload_max_filesize
 * One may want to be able to upload a 100MB file, but may not want the $_POST var,
 * with for example the text or HTML of a textarea to be 100MB and later stored in database.
 */
if ( ! defined( 'ROSARIO_POST_MAX_SIZE_LIMIT' ) )
{
	/**
	 * Fix a limit of 16MB based on MySQL max_allowed_packet default limit
	 * Limit size can be overriden in the config.inc.php file
	 */
	define( 'ROSARIO_POST_MAX_SIZE_LIMIT', 16 * 1024 * 1024 ); // 16MB in bytes.
}

if ( $_POST
	&& strlen( serialize( $_POST ) ) > ROSARIO_POST_MAX_SIZE_LIMIT )
{
	$post_max_size_limit = function( $value ) {
		if ( strlen( $value ) > ( ROSARIO_POST_MAX_SIZE_LIMIT / 4 ) )
		{
			// Reset value > limit / 4, or else we would send it in the HackingLog email!
			return 'ROSARIO_POST_MAX_SIZE_LIMIT / 4 reached.';
		}

		return $value;
	};

	array_rwalk( $_POST, $post_max_size_limit );

	array_rwalk( $_REQUEST, $post_max_size_limit );

	require_once 'ProgramFunctions/HackingLog.fnc.php';

	// Do not translate.
	$error[] = 'You are submitting too much data: over the ' .
		( ROSARIO_POST_MAX_SIZE_LIMIT / 1024 / 1024 ) .
		'M limit. Try reducing the data you are submitting.';

	HackingLog();
}