CVE-2023-2756: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: SQL Injection in GitHub repository pimcore/customer-data-framework prior to 3.3.10.
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: 7.2
Published: 2023-05-17T11:15Z
Repository: https://github.com/pimcore/customer-data-framework
Language: PHP
Files changed: src/Controller/Admin/SegmentAssignmentController.php
Commit date: 2023-05-16 17:49:32 +0200
Commit message: [Bug]: Fix Inheritable Segment query (#460)

* refactor query

* Apply php-cs-fixer changes

* fix changes were based on another vers

* Update SegmentAssignmentController.php

* task: also return empty when $`id` is not set

---------

Co-authored-by: kingjia90 <kingjia90@users.noreply.github.com>
Diff: diff --git a/src/Controller/Admin/SegmentAssignmentController.php b/src/Controller/Admin/SegmentAssignmentController.php
index eae14a2d..68f92f00 100644
--- a/src/Controller/Admin/SegmentAssignmentController.php
+++ b/src/Controller/Admin/SegmentAssignmentController.php
@@ -48,16 +48,21 @@ class SegmentAssignmentController extends AdminController
      *
      * @return JsonResponse
      */
     public function inheritableSegments(Request $request, SegmentManagerInterface $segmentManager)
     {
-        $id = $request->get('id') ?? '';
-        $type = $request->get('type') ?? '';
+        $id = $request->get('id');
+        $type = $request->get('type');
+        if (!$type || !$id) {
+            return $this->adminJson(['data' => []]);
+        }
 
         $db = \Pimcore\Db::get();
-        $parentIdStatement = sprintf('SELECT `%s` FROM `%s` WHERE `%s` = :value', $type === 'object' ? 'o_parentId' : 'parentId', $type.'s', $type === 'object' ? 'o_id' : 'id');
+        $parentIdStatement = sprintf('SELECT :parentIdField FROM %s WHERE :idField = :value', $db->quoteIdentifier($type . 's'));
         $parentId = $db->fetchOne($parentIdStatement, [
+            'parentIdField' => $type === 'object' ? 'o_parentId' : 'parentId',
+            'idField' => $type === 'object' ? 'o_id' : 'id',
             'value' => $id
         ]);
 
         $segments = $segmentManager->getSegmentsForElementId($parentId, $type);
         $data = array_map([$this, 'dehydrateSegment'], array_filter($segments));

Vulnerable code:         $id = $request->get('id') ?? '';
        $type = $request->get('type') ?? '';
        $parentIdStatement = sprintf('SELECT `%s` FROM `%s` WHERE `%s` = :value', $type === 'object' ? 'o_parentId' : 'parentId', $type.'s', $type === 'object' ? 'o_id' : 'id');
Fixed code:         $id = $request->get('id');
        $type = $request->get('type');
        if (!$type || !$id) {
            return $this->adminJson(['data' => []]);
        }
        $parentIdStatement = sprintf('SELECT :parentIdField FROM %s WHERE :idField = :value', $db->quoteIdentifier($type . 's'));
            'parentIdField' => $type === 'object' ? 'o_parentId' : 'parentId',
            'idField' => $type === 'object' ? 'o_id' : 'id',