CVE-2021-41161: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Combodo iTop is a web based IT Service Management tool. In versions prior to 3.0.0-beta6 the export CSV page don't properly escape the user supplied parameters, allowing for javascript injection into rendered csv files. Users are advised to upgrade. There are no known workarounds for this issue.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2022-04-21T17:15Z
Repository: https://github.com/Combodo/iTop
Language: PHP
Files changed: pages/csvimport.php
Commit date: 2021-10-19 11:32:05 +0200
Commit message: N°4361 - XSS in csvimport on develop

Diff: diff --git a/pages/csvimport.php b/pages/csvimport.php
index d3a8c7e5df..2cb3e0fb57 100644
--- a/pages/csvimport.php
+++ b/pages/csvimport.php
@@ -231,24 +231,22 @@ try {
 	 */
 	function ProcessCSVData(WebPage $oPage, $bSimulate = true)
 	{
 		$sClassName = utils::ReadParam('class_name', '', false, 'class');
 		// Class access right check for the import
-		if (UserRights::IsActionAllowed($sClassName, UR_ACTION_MODIFY) == UR_ALLOWED_NO)
-		{
+		if (UserRights::IsActionAllowed($sClassName, UR_ACTION_MODIFY) == UR_ALLOWED_NO) {
 			throw new CoreException(Dict::S('UI:ActionNotAllowed'));
 		}
 
 		$aResult = array();
 		$sCSVData = utils::ReadParam('csvdata', '', false, 'raw_data');
 		$sCSVDataTruncated = utils::ReadParam('csvdata_truncated', '', false, 'raw_data');
 		$sSeparator = utils::ReadParam('separator', ',', false, 'raw_data');
 		$sTextQualifier = utils::ReadParam('text_qualifier', '"', false, 'raw_data');
 		$bHeaderLine = (utils::ReadParam('header_line', '0') == 1);
 		$iSkippedLines = 0;
-		if (utils::ReadParam('box_skiplines', '0') == 1)
-		{
+		if (utils::ReadParam('box_skiplines', '0') == 1) {
 			$iSkippedLines = utils::ReadParam('nb_skipped_lines', '0');
 		}
 		$aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data');
 		$aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name');
 		$iCurrentStep = $bSimulate ? 4 : 5;
@@ -1148,11 +1146,11 @@ EOF
 			if (!$oDocument->IsEmpty())
 			{
 				$sCSVData = $oDocument->GetData();
 			}
 			break;
-			
+
 			default:
 			$sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data');
 		}
 		$sEncoding = utils::ReadParam('encoding', 'UTF-8');
 	
@@ -1513,11 +1511,11 @@ EOF
 		$oTabPaste = $oTabContainer->AddTab('UI:CSVImport:Tab:PasteData', Dict::S('UI:CSVImport:Tab:CopyPaste'));
 		$oFormPaste = FormUIBlockFactory::MakeStandard();
 		$oTabPaste->AddSubBlock($oFormPaste);
 
 
-		$sCSVData = utils::ReadParam('csvdata', '', false, 'raw_data');
+		$sCSVData = utils::ReadParam('csvdata', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
 		$oTextarea = new TextArea('csvdata', $sCSVData, '', 120, 30);
 		$oFieldPaste = FieldUIBlockFactory::MakeFromObject(Dict::S('UI:CSVImport:PasteData'), $oTextarea);
 		$oFormPaste->AddSubBlock($oFieldPaste);
 
 		$oFormPaste->AddSubBlock(InputUIBlockFactory::MakeForHidden("encoding", 'UTF-8'));

Vulnerable code: 		if (UserRights::IsActionAllowed($sClassName, UR_ACTION_MODIFY) == UR_ALLOWED_NO)
		{
		if (utils::ReadParam('box_skiplines', '0') == 1)
		{
			
		$sCSVData = utils::ReadParam('csvdata', '', false, 'raw_data');
Fixed code: 		if (UserRights::IsActionAllowed($sClassName, UR_ACTION_MODIFY) == UR_ALLOWED_NO) {
		if (utils::ReadParam('box_skiplines', '0') == 1) {

		$sCSVData = utils::ReadParam('csvdata', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);