CVE-2023-3673: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value:  SQL Injection in GitHub repository pimcore/pimcore prior to 10.5.24.
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-07-14T13:15Z
Repository: https://github.com/pimcore/pimcore
Language: PHP
Files changed: bundles/AdminBundle/Controller/Admin/LogController.php, bundles/AdminBundle/Controller/Admin/TranslationController.php, bundles/AdminBundle/Helper/QueryParams.php, models/Search/Backend/Data/Listing.php, models/Translation/Listing.php
Commit date: 2023-06-14 12:33:22 +0200
Commit message: [Task]: Improve Admin translation and application logger sorting (#15303)

* task: improve valid key for translation listing

* task: force the direction to be ASC/DESC since these are the only valid options

* task: quote application logger sorting setting

* task: add backend search grid valid order keys
Diff: diff --git a/bundles/AdminBundle/Controller/Admin/LogController.php b/bundles/AdminBundle/Controller/Admin/LogController.php
index 5dff214b32f6..e66aa070219b 100644
--- a/bundles/AdminBundle/Controller/Admin/LogController.php
+++ b/bundles/AdminBundle/Controller/Admin/LogController.php
@@ -65,11 +65,11 @@ class LogController extends AdminController implements KernelControllerEventInte
             $request->request->all(),
             $request->query->all()
         ));
 
         if ($sortingSettings['orderKey']) {
-            $qb->orderBy($sortingSettings['orderKey'], $sortingSettings['order']);
+            $qb->orderBy($db->quoteIdentifier($sortingSettings['orderKey']), $sortingSettings['order']);
         } else {
             $qb->orderBy('id', 'DESC');
         }
 
         $priority = $request->get('priority');
diff --git a/bundles/AdminBundle/Controller/Admin/TranslationController.php b/bundles/AdminBundle/Controller/Admin/TranslationController.php
index 4b62a1885e02..3d78730d7cba 100644
--- a/bundles/AdminBundle/Controller/Admin/TranslationController.php
+++ b/bundles/AdminBundle/Controller/Admin/TranslationController.php
@@ -441,10 +441,11 @@ class TranslationController extends AdminController
 
             $validLanguages = $admin ? Tool\Admin::getLanguages() : $this->getAdminUser()->getAllowedLanguagesForViewingWebsiteTranslations();
 
             $list->setOrder('asc');
             $list->setOrderKey($tableName . '.key', false);
+            $list->setLanguages($validLanguages);
 
             $sortingSettings = \Pimcore\Bundle\AdminBundle\Helper\QueryParams::extractSortingSettings(
                 array_merge($request->request->all(), $request->query->all())
             );
 
diff --git a/bundles/AdminBundle/Helper/QueryParams.php b/bundles/AdminBundle/Helper/QueryParams.php
index 26f1ffce74b7..d4a621c8e294 100644
--- a/bundles/AdminBundle/Helper/QueryParams.php
+++ b/bundles/AdminBundle/Helper/QueryParams.php
@@ -35,16 +35,16 @@ class QueryParams
         $sortParam = isset($params['sort']) ? $params['sort'] : false;
         if ($sortParam) {
             $sortParam = json_decode($sortParam, true);
             $sortParam = $sortParam[0];
 
+            $order = strtoupper($sortParam['direction']) === 'DESC' ? 'DESC' : 'ASC';
+
             if (substr($sortParam['property'], 0, 1) != '~') {
                 $orderKey = $sortParam['property'];
-                $order = $sortParam['direction'];
             } else {
                 $orderKey = $sortParam['property'];
-                $order = $sortParam['direction'];
 
                 $parts = explode('~', $orderKey);
 
                 $fieldname = $parts[2];
                 $groupKeyId = $parts[3];
diff --git a/models/Search/Backend/Data/Listing.php b/models/Search/Backend/Data/Listing.php
index c5a41490a9ee..bd03d3525bb8 100644
--- a/models/Search/Backend/Data/Listing.php
+++ b/models/Search/Backend/Data/Listing.php
@@ -50,6 +50,32 @@ class Listing extends \Pimcore\Model\Listing\AbstractListing
      */
     public function __construct()
     {
         $this->initDao(__CLASS__);
     }
+
+    /**
+     * @inheritdoc
+     */
+    public function isValidOrderKey($key)
+    {
+        return in_array(
+            $key,
+            [
+                'type',
+                'id',
+                'key',
+                'index',
+                'fullpath',
+                'maintype',
+                'subtype',
+                'published',
+                'creationDate',
+                'modificationDate',
+                'userOwner',
+                'userModification',
+                'data',
+                'properties'
+            ]
+        );
+    }
 }
diff --git a/models/Translation/Listing.php b/models/Translation/Listing.php
index 96d5a930e90a..c46dd27529ef 100644
--- a/models/Translation/Listing.php
+++ b/models/Translation/Listing.php
@@ -49,10 +49,18 @@ class Listing extends Model\Listing\AbstractListing
      *
      * @var string[]|null
      */
     protected ?array $languages = null;
 
+    /**
+     * @inheritdoc
+     */
+    public function isValidOrderKey($key)
+    {
+        return in_array($key, ['key', 'type']) || in_array($key, $this->getLanguages());
+    }
+
     /**
      * @return string
      */
     public function getDomain(): string
     {

Vulnerable code:             $qb->orderBy($sortingSettings['orderKey'], $sortingSettings['order']);
                $order = $sortParam['direction'];
                $order = $sortParam['direction'];
Fixed code:             $qb->orderBy($db->quoteIdentifier($sortingSettings['orderKey']), $sortingSettings['order']);
            $list->setLanguages($validLanguages);
            $order = strtoupper($sortParam['direction']) === 'DESC' ? 'DESC' : 'ASC';


    /**
     * @inheritdoc
     */
    public function isValidOrderKey($key)
    {
        return in_array(
            $key,
            [
                'type',
                'id',
                'key',
                'index',
                'fullpath',
                'maintype',
                'subtype',
                'published',
                'creationDate',
                'modificationDate',
                'userOwner',
                'userModification',
                'data',
                'properties'
            ]
        );
    }
    /**
     * @inheritdoc
     */
    public function isValidOrderKey($key)
    {
        return in_array($key, ['key', 'type']) || in_array($key, $this->getLanguages());
    }