CVE-2019-20107: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: Multiple SQL injection vulnerabilities in TestLink through 1.9.19 allows remote authenticated users to execute arbitrary SQL commands via the (1) tproject_id parameter to keywordsView.php; the (2) req_spec_id parameter to reqSpecCompareRevisions.php; the (3) requirement_id parameter to reqCompareVersions.php; the (4) build_id parameter to planUpdateTC.php; the (5) tplan_id parameter to newest_tcversions.php; the (6) tplan_id parameter to tcCreatedPerUserGUI.php; the (7) tcase_id parameter to tcAssign2Tplan.php; or the (8) testcase_id parameter to tcCompareVersions.php. Authentication is often easy to achieve: a guest account, that can execute this attack, can be created by anyone in the default configuration.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
CVSS v3 base score: 8.8
Published: 2020-03-05T13:15Z
Repository: https://github.com/TestLinkOpenSourceTRMS/testlink-code
Language: PHP
Files changed: lib/plan/tc_exec_unassign_all.php, lib/results/testCasesWithCF.php
Commit date: 2019-12-31 12:06:22 +0100
Commit message: fix: security #8829

Diff: diff --git a/lib/plan/tc_exec_unassign_all.php b/lib/plan/tc_exec_unassign_all.php
index b17717754f..b258d57fc4 100644
--- a/lib/plan/tc_exec_unassign_all.php
+++ b/lib/plan/tc_exec_unassign_all.php
@@ -2,16 +2,11 @@
 /** 
  * TestLink Open Source Project - http://testlink.sourceforge.net/
  * This script is distributed under the GNU General Public License 2 or later. 
  *
  * @package		TestLink
- * @author		Andreas Simon
- * @copyright	2005-2010, TestLink community 
- * @version		CVS: $Id: tc_exec_unassign_all.php,v 1.3 2010/07/26 19:00:57 asimon83 Exp $
- * @link		http://www.teamst.org/index.php
- *
- * @internal revisions:
+ * @copyright	2005-2019, TestLink community 
  * 
  */
 
 require_once(dirname(__FILE__)."/../../config.inc.php");
 require_once("common.php");
@@ -67,15 +62,16 @@ function init_args() {
 	
 	$args = new stdClass();
 	
 	$_REQUEST = strings_stripSlashes($_REQUEST);
 	
-	$args->build_id = isset($_REQUEST['build_id']) ? $_REQUEST['build_id'] : 0;
+	$args->build_id = isset($_REQUEST['build_id']) ? 
+	                  intval($_REQUEST['build_id']) : 0;
 	$args->confirmed = isset($_REQUEST['confirmed']) && $_REQUEST['confirmed'] == 'yes' ? true : false;
 	
 	$args->user_id = $_SESSION['userID'];
-	$args->testproject_id = $_SESSION['testprojectID'];
+	$args->testproject_id = intval($_SESSION['testprojectID']);
 	$args->testproject_name = $_SESSION['testprojectName'];
 	
 	$args->refreshTree = isset($_SESSION['setting_refresh_tree_on_action']) ?
 	                     $_SESSION['setting_refresh_tree_on_action'] : false;
 	
diff --git a/lib/results/testCasesWithCF.php b/lib/results/testCasesWithCF.php
index d7c7101b05..c150169ec0 100644
--- a/lib/results/testCasesWithCF.php
+++ b/lib/results/testCasesWithCF.php
@@ -6,12 +6,10 @@
  * @filesource	testCasesWithCF.php
  * @author Amit Khullar - amkhullar@gmail.com
  *
  * For a test plan, list test cases with Execution Custom Field Data
  *
- * @internal revisions
- * @since 1.9.7
  */
 require_once("../../config.inc.php");
 require_once("common.php");
 require_once('exttable.class.php');
 testlinkInitPage($db,false,false,"checkRights");
@@ -140,37 +138,40 @@ $smarty->display($templateCfg->template_dir . $templateCfg->default_template);
  returns:
 
  */
 function init_args(&$dbHandler)
 {
-    $argsObj = new stdClass();
+  $argsObj = new stdClass();
 	$argsObj->doIt = false;
-    $argsObj->showPlatforms = false;
-    $argsObj->tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
-    $argsObj->tproject_name = isset($_SESSION['testprojectName']) ? $_SESSION['testprojectName'] : '';
+  $argsObj->showPlatforms = false;
+  $argsObj->tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
+  $argsObj->tproject_id = intval($argsObj->tproject_id);
 
-    $argsObj->tplan_name = '';
-    $argsObj->tplan_id = isset($_REQUEST['tplan_id']) ? $_REQUEST['tplan_id'] : 0;
-    if($argsObj->tplan_id == 0)
-    {
-        $argsObj->tplan_id = isset($_SESSION['testplanID']) ? $_SESSION['testplanID'] : 0;
-    }
 
-    if($argsObj->tplan_id > 0)
-    {
+  $argsObj->tproject_name = isset($_SESSION['testprojectName']) ? $_SESSION['testprojectName'] : '';
+
+  $argsObj->tplan_name = '';
+  $argsObj->tplan_id = isset($_REQUEST['tplan_id']) ? $_REQUEST['tplan_id'] : 0;
+  $argsObj->tplan_id = intval($argsObj->tplan_id);
+
+  if ($argsObj->tplan_id == 0) {
+    $argsObj->tplan_id = isset($_SESSION['testplanID']) ? $_SESSION['testplanID'] : 0;
+  }
+
+  if($argsObj->tplan_id > 0) {
     	$tplan_mgr = new testplan($dbHandler);
         $tplan_info = $tplan_mgr->get_by_id($argsObj->tplan_id);
         $argsObj->tplan_name = $tplan_info['name'];
 
 		$argsObj->doIt = $tplan_mgr->count_testcases($argsObj->tplan_id) > 0;
 		$argsObj->showPlatforms = $tplan_mgr->hasLinkedPlatforms($argsObj->tplan_id);
 		$getOpt = array('outputFormat' => 'map');
 		$argsObj->platforms = $tplan_mgr->getPlatforms($argsObj->tplan_id,$getOpt);
 		unset($tplan_mgr);
-    }
+  }
 
-    return $argsObj;
+  return $argsObj;
 }
 
 
 
 function initializeGui(&$dbHandler,&$argsObj)
@@ -308,7 +309,6 @@ function getColumnsDefinition($showPlatforms,$customFields,$platforms)
 
 
 function checkRights(&$db,&$user)
 {
 	return $user->hasRight($db,'testplan_metrics');
-}
-?>
\ No newline at end of file
+}
\ No newline at end of file

Vulnerable code:  * @author		Andreas Simon
 * @copyright	2005-2010, TestLink community 
 * @version		CVS: $Id: tc_exec_unassign_all.php,v 1.3 2010/07/26 19:00:57 asimon83 Exp $
 * @link		http://www.teamst.org/index.php
 *
 * @internal revisions:
	$args->build_id = isset($_REQUEST['build_id']) ? $_REQUEST['build_id'] : 0;
	$args->testproject_id = $_SESSION['testprojectID'];
 * @internal revisions
 * @since 1.9.7
    $argsObj = new stdClass();
    $argsObj->showPlatforms = false;
    $argsObj->tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
    $argsObj->tproject_name = isset($_SESSION['testprojectName']) ? $_SESSION['testprojectName'] : '';
    $argsObj->tplan_name = '';
    $argsObj->tplan_id = isset($_REQUEST['tplan_id']) ? $_REQUEST['tplan_id'] : 0;
    if($argsObj->tplan_id == 0)
    {
        $argsObj->tplan_id = isset($_SESSION['testplanID']) ? $_SESSION['testplanID'] : 0;
    }
    if($argsObj->tplan_id > 0)
    {
    }
    return $argsObj;
}
?>
Fixed code:  * @copyright	2005-2019, TestLink community 
	$args->build_id = isset($_REQUEST['build_id']) ? 
	                  intval($_REQUEST['build_id']) : 0;
	$args->testproject_id = intval($_SESSION['testprojectID']);
  $argsObj = new stdClass();
  $argsObj->showPlatforms = false;
  $argsObj->tproject_id = isset($_SESSION['testprojectID']) ? $_SESSION['testprojectID'] : 0;
  $argsObj->tproject_id = intval($argsObj->tproject_id);
  $argsObj->tproject_name = isset($_SESSION['testprojectName']) ? $_SESSION['testprojectName'] : '';

  $argsObj->tplan_name = '';
  $argsObj->tplan_id = isset($_REQUEST['tplan_id']) ? $_REQUEST['tplan_id'] : 0;
  $argsObj->tplan_id = intval($argsObj->tplan_id);

  if ($argsObj->tplan_id == 0) {
    $argsObj->tplan_id = isset($_SESSION['testplanID']) ? $_SESSION['testplanID'] : 0;
  }

  if($argsObj->tplan_id > 0) {
  }
  return $argsObj;
}