CVE-2022-4592 (published 2022-12-18T08:15Z)

A vulnerability was found in luckyshot CRMx and classified as critical. This issue affects the function get/save/delete/comment/commentdelete of the file index.php. The manipulation leads to sql injection. The attack may be initiated remotely. The name of the patch is 8c62d274986137d6a1d06958a6f75c3553f45f8f. It is recommended to apply a patch to fix this issue. The identifier VDB-216185 was assigned to this vulnerability.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
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.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/luckyshot/CRMx
commit_details: repo_url: https://github.com/luckyshot/CRMx
author: Xavi Esteve
author_date: 2022-11-22 11:46:18+01:00
msg: FIX SQL Injection Vulnerabilities following report by pm_security_report
repository: repo_url: https://github.com/luckyshot/CRMx
repo_name: luckyshot/CRMx
description: CRMx is a super-flexible micro-CRM system for personal, freelance and small businesses. It can be customized very quickly for Customer Relationship Management, Lead Management System, Project Management, To-Do List or any other usage due to its flexibility in customization and scalable code. CRMx allows unlimited users to work in the same or different environments very flexibly. CRMx works through a RESTful API which allows third-party services and other software to interact neatly. CRMx also has a User Access Control system (UAC) to define permissions for each user and have maximum control over the organization.
repo_language: PHP
owner: luckyshot
file_changes: filename: index.php
change_type: ModificationType.MODIFY
diff: @@ -212,7 +212,7 @@ function search($s='') {
 		foreach ($w as &$wi) {
 			$wi = "(name LIKE  '%".$c->real_escape_string($wi)."%' OR form LIKE  '%".$c->real_escape_string($wi)."%' OR comments LIKE  '%".$c->real_escape_string($wi)."%') ";
 		}
-		$q = "SELECT id, name, form FROM ".$_SESSION['dbprefix']."people WHERE ". implode(' AND ', $w) ."  ORDER BY name ASC LIMIT 0, 50";
+		$q = "SELECT `id`, `name`, `form` FROM `".$_SESSION['dbprefix']."people` WHERE ". implode(' AND ', $w) ." ORDER BY `name` ASC LIMIT 0, 50";
 		$people = db($q, $c);
 
 		foreach($people as &$person) {
@@ -247,9 +247,9 @@ function get($detail) {
 	}else{
 		global $c;
 		if (is_numeric($detail)) {
-			$people = db("SELECT * FROM ".$_SESSION['dbprefix']."people WHERE id = ".$c->real_escape_string($detail)." LIMIT 1", $c);
+			$people = db("SELECT * FROM `".$_SESSION['dbprefix']."people` WHERE `id` = '".$c->real_escape_string($detail)."' LIMIT 1;", $c);
 		}else{
-			$people = db("SELECT * FROM ".$_SESSION['dbprefix']."people WHERE name LIKE '%".$c->real_escape_string($detail)."%' OR form LIKE '%".$c->real_escape_string($detail)."%' ORDER BY updated DESC LIMIT 1", $c);
+			$people = db("SELECT * FROM `".$_SESSION['dbprefix']."people` WHERE `name` LIKE '%".$c->real_escape_string($detail)."%' OR `form` LIKE '%".$c->real_escape_string($detail)."%' ORDER BY `updated` DESC LIMIT 1;", $c);
 		}
 		if ($people) {
 			$people = $people[0];
@@ -297,12 +297,12 @@ function save() {
 		}
 //var_dump($array);
 		if ($_POST['id']) { // update details
-			$q = "UPDATE ".$_SESSION['dbprefix']."people SET
-				form = '".$c->real_escape_string(json_encode($array))."',
-				name =  '".$c->real_escape_string($_POST['name'])."',
-				`updated` =  '".time()."' WHERE  id = ".($_POST['id']).";";
+			$q = "UPDATE `".$_SESSION['dbprefix']."people` SET
+				`form` = '".$c->real_escape_string(json_encode($array))."',
+				`name` = '".$c->real_escape_string($_POST['name'])."',
+				`updated` = '".time()."' WHERE `id` = '".$c->real_escape_string($_POST['id'])."';";
 		}else{ // create new
-			$q = "INSERT INTO ".$_SESSION['dbprefix']."people VALUES (
+			$q = "INSERT INTO `".$_SESSION['dbprefix']."people` VALUES (
 				NULL,
 				'".$c->real_escape_string($_POST['name'])."',
 				'".$c->real_escape_string(json_encode($array))."',
@@ -319,7 +319,7 @@ function save() {
 				$response = json(array('status'=>'success','message'=>'Contact details saved'));
 			}else{
 				// Get the ID
-				$q = "SELECT id from ".$_SESSION['dbprefix']."people ORDER BY id DESC LIMIT 1";
+				$q = "SELECT `id` FROM `".$_SESSION['dbprefix']."people` ORDER BY `id` DESC LIMIT 1;";
 				$id = db($q, $c);
 				$response = json(array('id'=>$id[0]['id'],'status'=>'success','message'=>'New contact created'));
 			}
@@ -348,7 +348,7 @@ function delete($id) {
 		$response = json(array('status'=>'error','message'=>"Your user cannot delete"));
 	}else{
 		global $c;
-		$deletion = db("DELETE FROM ".$_SESSION['dbprefix']."people WHERE id = ".$c->real_escape_string($id)."", $c);
+		$deletion = db("DELETE FROM `".$_SESSION['dbprefix']."people` WHERE `id` = '".$c->real_escape_string($id)."';", $c);
 
 		if ($deletion) {
 			$response = json(array('status'=>'success','message'=>'Contact deleted'));
@@ -386,7 +386,7 @@ function comment($id) {
 		json(array('status'=>'error','message'=>$lang['writecommentfirst']));
 	}else{
 		global $c;
-		$comments = db("SELECT comments FROM ".$_SESSION['dbprefix']."people WHERE id = ".$c->real_escape_string($_POST['id'])."", $c);
+		$comments = db("SELECT `comments` FROM `".$_SESSION['dbprefix']."people` WHERE id = '".$c->real_escape_string($_POST['id'])."';", $c);
 		$comments = json_decode($comments[0]['comments'], true);
 //var_dump($comments);
 		array_unshift($comments, array(
@@ -395,7 +395,7 @@ function comment($id) {
 			'date' => date('c', time()), // iso 8601 format
 			'text' => $_POST['comment']
 		));
-		$q = "UPDATE ".$_SESSION['dbprefix']."people SET comments = '".$c->real_escape_string(json_encode($comments))."' WHERE id = ".$c->real_escape_string($_POST['id'])."";
+		$q = "UPDATE `".$_SESSION['dbprefix']."people` SET `comments` = '".$c->real_escape_string(json_encode($comments))."' WHERE `id` = '".$c->real_escape_string($_POST['id'])."';";
 		$result = db($q, $c);
 
 		if ($result) {
@@ -419,7 +419,7 @@ function commentdelete($id) {
 	}else{
 		global $c;
 		// load comments from person
-		$person = db("SELECT id,comments FROM ".$_SESSION['dbprefix']."people WHERE comments LIKE '%".$c->real_escape_string($id)."%' ORDER BY updated DESC LIMIT 1", $c);
+		$person = db("SELECT `id`, `comments` FROM `".$_SESSION['dbprefix']."people` WHERE `comments` LIKE '%".$c->real_escape_string($id)."%' ORDER BY `updated` DESC LIMIT 1;", $c);
 		$person[0]['comments'] = json_decode($person[0]['comments'], true);
 		// remove from array
 		foreach($person[0]['comments'] as $key => $comment) {
@@ -429,9 +429,9 @@ function commentdelete($id) {
 			}
 		}
 		// update person
-		$result = db("UPDATE ".$_SESSION['dbprefix']."people SET
-			comments = '".$c->real_escape_string(json_encode($person[0]['comments']))."'
-			WHERE  id = ".($person[0]['id']).";", $c);
+		$result = db("UPDATE `".$_SESSION['dbprefix']."people` SET
+			`comments` = '".$c->real_escape_string(json_encode($person[0]['comments']))."'
+			WHERE `id` = '".($person[0]['id'])."';", $c);
 		if ($result) {
 			$response = json(array(
 				'status'=>'success',

programming_language: PHP