wambosec/csi-sqli-rl huggingface dataset:
Security advisory GHSA-97jv-2hp6-3frj: Dolibarr SQL injection vulnerability in user/card.php
Package: dolibarr/dolibarr (composer), vulnerable version: 8.0.3, fixed in: 8.0.4
CWE: CWE-89
Files changed by the fix:
htdocs/user/card.php
htdocs/user/class/user.class.php

Fix diff:
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index 6743078c9d265..f0b3fb819f280 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -350,7 +350,7 @@
 				$object->accountancy_code = GETPOST("accountancy_code",'alpha');
 				$object->openid = GETPOST("openid",'alpha');
 				$object->fk_user = GETPOST("fk_user",'int') > 0 ? GETPOST("fk_user",'int') : 0;
-				$object->employee = GETPOST('employee','alphanothtml');
+				$object->employee = GETPOST('employee','int');
 
 				$object->thm = GETPOST("thm",'alphanohtml') != '' ? GETPOST("thm",'alphanohtml') : '';
 				$object->tjm = GETPOST("tjm",'alphanohtml') != '' ? GETPOST("tjm",'alphanohtml') : '';
diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
index 161cea20e7745..ef2b828f6e577 100644
--- a/htdocs/user/class/user.class.php
+++ b/htdocs/user/class/user.class.php
@@ -1405,12 +1405,12 @@ function update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosy
 		$sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
 		$sql.= " lastname = '".$this->db->escape($this->lastname)."'";
 		$sql.= ", firstname = '".$this->db->escape($this->firstname)."'";
-		$sql.= ", employee = ".$this->employee;
+		$sql.= ", employee = ".(int) $this->employee;
 		$sql.= ", login = '".$this->db->escape($this->login)."'";
 		$sql.= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null");
 		$sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null");	// 'man' or 'woman'
 		$sql.= ", birth=".(strval($this->birth)!='' ? "'".$this->db->idate($this->birth)."'" : 'null');
-		if (! empty($user->admin)) $sql.= ", admin = ".$this->admin;	// admin flag can be set/unset only by an admin user
+		if (! empty($user->admin)) $sql.= ", admin = ".(int) $this->admin;	// admin flag can be set/unset only by an admin user
 		$sql.= ", address = '".$this->db->escape($this->address)."'";
 		$sql.= ", zip = '".$this->db->escape($this->zip)."'";
 		$sql.= ", town = '".$this->db->escape($this->town)."'";
@@ -1502,7 +1502,7 @@ function update($user, $notrigger=0, $nosyncmember=0, $nosyncmemberpass=0, $nosy
 						$adh->zip=$this->zip;
 						$adh->state_id=$this->state_id;
 						$adh->country_id=$this->country_id;
-						
+
 						$adh->email=$this->email;
 						$adh->skype=$this->skype;
 						$adh->phone=$this->office_phone;
Security advisory GHSA-9c2p-jw8p-f84v: SQL Injection in sequelize
Package: sequelize (npm), vulnerable version: 3.19.3, fixed in: 3.20.0
CWE: CWE-89
Files changed by the fix:
lib/sql-string.js

Fix diff:
diff --git a/changelog.md b/changelog.md
index 3c66cf25603e..01a1afe6186a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,6 +3,7 @@
 - [ADDED] `validationFailed` hook [#1626](https://github.com/sequelize/sequelize/issues/1626)
 - [FIXED] Mark index as `unique: true` when `type: 'UNIQUE'`. Fixes [#5351](https://github.com/sequelize/sequelize/issues/5351)
 - [ADDED[ Support for IEEE floating point literals in postgres and sqlite [#5194](https://github.com/sequelize/sequelize/issues/5194)
+- [FIXED] Improper escaping of bound arrays of strings on Postgres, SQLite, and Microsoft SQL Server
 
 # 3.19.3
 - [FIXED] `updatedAt` and `createdAt` values are now set before validation [#5367](https://github.com/sequelize/sequelize/pull/5367)
diff --git a/lib/sql-string.js b/lib/sql-string.js
index d9916eaddc98..e3c6206d5b38 100644
--- a/lib/sql-string.js
+++ b/lib/sql-string.js
@@ -48,7 +48,7 @@ SqlString.escape = function(val, timeZone, dialect, format) {
   }
 
   if (Array.isArray(val)) {
-    var escape = _.partialRight(SqlString.escape, timeZone, dialect);
+    var escape = _.partial(SqlString.escape, _, timeZone, dialect, format);
     if (dialect === 'postgres' && !format) {
       return dataTypes.ARRAY.prototype.stringify(val, {escape: escape});
     }
diff --git a/test/integration/sequelize.test.js b/test/integration/sequelize.test.js
index d80a1d539e6d..7c5239811912 100755
--- a/test/integration/sequelize.test.js
+++ b/test/integration/sequelize.test.js
@@ -583,6 +583,15 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
       });
     });
 
+    if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') {
+      it ('does not improperly escape arrays of strings bound to named parameters', function() {
+        var logSql;
+        return this.sequelize.query('select :stringArray as foo', { raw: true, replacements: { stringArray: [ '"string"' ] }, logging: function(s) { logSql = s; } }).then(function(result) {
+          expect(result[0]).to.deep.equal([{ foo: '"string"' }]);
+        });
+      });
+    }
+
     it('throw an exception when binds passed with object and numeric $1 is also present', function() {
       var self = this;
       var typeCast = (dialect === 'postgres') ? '::int' : '';
Security advisory GHSA-9cq5-xgg4-x477: SQL Injection in showdoc
Package: showdoc/showdoc (composer), vulnerable version: v2.10.2, fixed in: 2.10.3
CWE: CWE-89
Files changed by the fix:
server/Application/Api/Controller/AdminUserController.class.php

Fix diff:
diff --git a/server/Application/Api/Controller/AdminUserController.class.php b/server/Application/Api/Controller/AdminUserController.class.php
index edf0f559c..9e966b8cd 100644
--- a/server/Application/Api/Controller/AdminUserController.class.php
+++ b/server/Application/Api/Controller/AdminUserController.class.php
@@ -76,7 +76,7 @@ public function addUser(){
         $this->checkAdmin();
         $username = I("post.username");
         $password = I("post.password");
-        $uid = I("post.uid");
+        $uid = I("post.uid/d");
         $name = I("post.name");
         if(!$username){
             $this->sendError(10101,'用户名不允许为空');
Security advisory GHSA-c7fc-cm7p-92r2: Openstack ironic-inspector has SQL injection vulnerability in node_cache
Package: ironic-inspector (pypi), vulnerable version: 5.0.1, fixed in: 5.0.2
CWE: CWE-89
Files changed by the fix:
ironic_inspector/node_cache.py

Fix diff:
diff --git a/ironic_inspector/node_cache.py b/ironic_inspector/node_cache.py
index 0a109e07e..a3f324ea0 100644
--- a/ironic_inspector/node_cache.py
+++ b/ironic_inspector/node_cache.py
@@ -18,6 +18,7 @@
 import copy
 import datetime
 import json
+import operator
 
 from automaton import exceptions as automaton_errors
 from ironicclient import exceptions
@@ -30,7 +31,6 @@
 from oslo_utils import uuidutils
 import six
 from sqlalchemy.orm import exc as orm_errors
-from sqlalchemy import text
 
 from ironic_inspector.common.i18n import _
 from ironic_inspector.common import ironic as ir_utils
@@ -807,14 +807,11 @@ def find_node(**attributes):
 
         LOG.debug('Trying to use %s of value %s for node look up',
                   name, value)
-        value_list = []
-        for v in value:
-            value_list.append("name='%s' AND value='%s'" % (name, v))
-        stmt = ('select distinct node_uuid from attributes where ' +
-                ' OR '.join(value_list))
-        rows = (db.model_query(db.Attribute.node_uuid).from_statement(
-            text(stmt)).all())
-        found.update(row.node_uuid for row in rows)
+        query = db.model_query(db.Attribute.node_uuid)
+        pairs = [(db.Attribute.name == name) &
+                 (db.Attribute.value == v) for v in value]
+        query = query.filter(six.moves.reduce(operator.or_, pairs))
+        found.update(row.node_uuid for row in query.distinct().all())
 
     if not found:
         raise utils.NotFoundInCacheError(_(
diff --git a/ironic_inspector/test/unit/test_node_cache.py b/ironic_inspector/test/unit/test_node_cache.py
index d6803c00a..07fcc439d 100644
--- a/ironic_inspector/test/unit/test_node_cache.py
+++ b/ironic_inspector/test/unit/test_node_cache.py
@@ -303,6 +303,11 @@ def test_already_finished(self):
         self.assertRaises(utils.Error, node_cache.find_node,
                           bmc_address='1.2.3.4')
 
+    def test_input_filtering(self):
+        self.assertRaises(utils.NotFoundInCacheError,
+                          node_cache.find_node,
+                          bmc_address="' OR ''='")
+
 
 class TestNodeCacheCleanUp(test_base.NodeTest):
     def setUp(self):
diff --git a/releasenotes/notes/find-node-input-filtering-e8ea529252e80739.yaml b/releasenotes/notes/find-node-input-filtering-e8ea529252e80739.yaml
new file mode 100644
index 000000000..f5e0b3f7d
--- /dev/null
+++ b/releasenotes/notes/find-node-input-filtering-e8ea529252e80739.yaml
@@ -0,0 +1,7 @@
+---
+security:
+  - |
+    Fixes insufficient input filtering when looking up a node by information
+    from the introspection data. It could potentially allow SQL injections
+    via the ``/v1/continue`` API endpoint. See `story 2005678
+    <https://storyboard.openstack.org/#!/story/2005678>`_ for details.
Security advisory GHSA-f2mf-q878-gh58: Parsl Monitoring Visualization Vulnerable to SQL Injection
Package: parsl (pypi), vulnerable version: 2025.12.29, fixed in: 2026.01.05
CWE: CWE-89
Files changed by the fix:
parsl/monitoring/visualization/views.py

Fix diff:
diff --git a/parsl/monitoring/visualization/views.py b/parsl/monitoring/visualization/views.py
index 8e34119143..02e7b04a1b 100644
--- a/parsl/monitoring/visualization/views.py
+++ b/parsl/monitoring/visualization/views.py
@@ -1,4 +1,5 @@
 import pandas as pd
+import sqlalchemy
 from flask import current_app as app
 from flask import render_template
 
@@ -143,9 +144,9 @@ def workflow_dag_details(workflow_id, path):
                                        FROM status
                                        WHERE status.task_id = task.task_id and status.run_id = task.run_id
                                       )
-               WHERE task.run_id='%s'""" % (workflow_id)
+               WHERE task.run_id=:run_id"""
 
-    df_tasks = pd.read_sql_query(query, db.engine)
+    df_tasks = pd.read_sql_query(sqlalchemy.text(query), db.engine, params={"run_id": workflow_id})
 
     group_by_apps = (path == "group_by_apps")
     return render_template('dag.html',
@@ -166,10 +167,11 @@ def workflow_resources(workflow_id):
                                message="Workflow %s does not have any resource usage records." % workflow_id)
 
     df_task = queries.tasks_for_workflow(workflow_id, db.engine)
-    df_task_tries = pd.read_sql_query("""SELECT task.task_id, task_func_name,
-                                      task_try_time_launched, task_try_time_running, task_try_time_returned from task, try
-                                      WHERE task.task_id = try.task_id AND task.run_id='%s' and try.run_id='%s'"""
-                                      % (workflow_id, workflow_id), db.engine)
+
+    query = """SELECT task.task_id, task_func_name,
+               task_try_time_launched, task_try_time_running, task_try_time_returned from task, try
+               WHERE task.task_id = try.task_id AND task.run_id=:run_id and try.run_id=task.run_id"""
+    df_task_tries = pd.read_sql_query(query, db.engine, params={"run_id": workflow_id})
     df_node = queries.nodes_for_workflow(workflow_id, db.engine)
 
     return render_template('resource_usage.html', workflow_details=workflow_details,
Security advisory GHSA-ffwf-47x2-jpr8: Matrix-appservice-irc vulnerable to sql injection via roomIds argument
Package: matrix-appservice-irc (npm), vulnerable version: 0.35.1, fixed in: 0.36.0
CWE: CWE-89
Files changed by the fix:
src/datastore/postgres/PgDataStore.ts

Fix diff:
diff --git a/changelog.d/1619.bugfix b/changelog.d/1619.bugfix
new file mode 100644
index 000000000..5b156125b
--- /dev/null
+++ b/changelog.d/1619.bugfix
@@ -0,0 +1 @@
+Prevent possible attack by provisisioning a room with a specific roomID.
diff --git a/src/datastore/postgres/PgDataStore.ts b/src/datastore/postgres/PgDataStore.ts
index e007f3c6c..c3c17090e 100644
--- a/src/datastore/postgres/PgDataStore.ts
+++ b/src/datastore/postgres/PgDataStore.ts
@@ -661,8 +661,9 @@ export class PgDataStore implements DataStore {
 
     public async getRoomsVisibility(roomIds: string[]) {
         const map: {[roomId: string]: "public"|"private"} = {};
-        const list = `('${roomIds.join("','")}')`;
-        const res = await this.pgPool.query(`SELECT room_id, visibility FROM room_visibility WHERE room_id IN ${list}`);
+        const res = await this.pgPool.query("SELECT room_id, visibility FROM room_visibility WHERE room_id IN $1", [
+            roomIds,
+        ]);
         for (const row of res.rows) {
             map[row.room_id] = row.visibility ? "public" : "private";
         }
Security advisory GHSA-fj74-qxj7-r3vc: AVideo has SQL Injection via Partial Prepared Statement — videos_id Concatenated Directly into Query
Package: wwbn/avideo (composer), vulnerable version: 25.0, fixed in: 26.0
CWE: CWE-89
Files changed by the fix:
objects/functions.php
objects/like.php

Fix diff:
diff --git a/objects/functions.php b/objects/functions.php
index 97e403645f4b..cc90ceb2e587 100644
--- a/objects/functions.php
+++ b/objects/functions.php
@@ -6538,7 +6538,9 @@ function videosHashToID($hash_of_videos_id)
     if (preg_match('/^\.([0-9a-z._-]+)/i', $hash_of_videos_id, $matches)) {
         $hash_of_videos_id = hashToID($matches[1]);
     }
-    return $hash_of_videos_id;
+    // Always return an integer — prevents SQL injection on any caller that
+    // embeds this value directly without a prepared statement placeholder.
+    return intval($hash_of_videos_id);
 }
 
 /**
diff --git a/objects/like.php b/objects/like.php
index e7e2257a2acf..e791f594f8b1 100644
--- a/objects/like.php
+++ b/objects/like.php
@@ -20,7 +20,7 @@ public function __construct($like, $videos_id)
             header('Content-Type: application/json');
             die('{"error":"'.__("Permission denied").'"}');
         }
-        $this->videos_id = $videos_id;
+        $this->videos_id = intval($videos_id);
         $this->users_id = User::getId();
         $this->load();
         // if click again in the same vote, remove the vote
@@ -81,8 +81,8 @@ private function getLike()
             header('Content-Type: application/json');
             die('{"error":"You must have user and videos set to get a like"}');
         }
-        $sql = "SELECT * FROM likes WHERE users_id = ? AND videos_id = ".$this->videos_id." LIMIT 1;";
-        $res = sqlDAL::readSql($sql, "i", [$this->users_id]);
+        $sql = "SELECT * FROM likes WHERE users_id = ? AND videos_id = ? LIMIT 1;";
+        $res = sqlDAL::readSql($sql, "ii", [$this->users_id, $this->videos_id]);
         $dbLike = sqlDAL::fetchAssoc($res);
         sqlDAL::close($res);
         return $dbLike;
@@ -102,7 +102,7 @@ private function save()
             $sql = "INSERT INTO likes (`like`,users_id, videos_id, created, modified) VALUES (?, ?, ?, now(), now());";
             $res = sqlDAL::writeSql($sql, "iii", [$this->like, $this->users_id, $this->videos_id]);
         }
-        
+
         $cacheHandler = new VideoCacheHandler($this->videos_id);
         $cacheHandler->deleteCache();
         return $res;
Security advisory GHSA-fqcv-8859-86x2: CoreShop Vulnerable to SQL Injection via Admin customer-company-modifier
Package: coreshop/core-shop (composer), vulnerable version: 4.1.8, fixed in: 4.1.9
CWE: CWE-564
Files changed by the fix:
src/CoreShop/Bundle/CoreBundle/Controller/CustomerTransformerController.php

Fix diff:
diff --git a/src/CoreShop/Bundle/CoreBundle/Controller/CustomerTransformerController.php b/src/CoreShop/Bundle/CoreBundle/Controller/CustomerTransformerController.php
index 6c0de28b5b..90fb1c0cc2 100644
--- a/src/CoreShop/Bundle/CoreBundle/Controller/CustomerTransformerController.php
+++ b/src/CoreShop/Bundle/CoreBundle/Controller/CustomerTransformerController.php
@@ -41,7 +41,7 @@ public function checkForNameDuplicatesAction(Request $request): JsonResponse
 
         if ($value !== null) {
             $list = $this->getCompanyRepository()->getList();
-            $list->addConditionParam(sprintf('name LIKE "%%%s%%"', (string) $value));
+            $list->addConditionParam('name LIKE ?', '%' . $value . '%');
             $foundObjects = $list->getData();
         }
Security advisory GHSA-g2mc-fqqc-hxg3: Pimcore Path Traversal Vulnerability in AdminBundle/Controller/Reports/CustomReportController.php
Package: pimcore/pimcore (composer), vulnerable version: v10.5.17, fixed in: 10.5.18
CWE: CWE-22
Files changed by the fix:
bundles/AdminBundle/Controller/Reports/CustomReportController.php

Fix diff:
diff --git a/bundles/AdminBundle/Controller/Reports/CustomReportController.php b/bundles/AdminBundle/Controller/Reports/CustomReportController.php
index 8b8f790871e..dd04a10cf5f 100644
--- a/bundles/AdminBundle/Controller/Reports/CustomReportController.php
+++ b/bundles/AdminBundle/Controller/Reports/CustomReportController.php
@@ -24,6 +24,7 @@
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\ResponseHeaderBag;
 use Symfony\Component\Routing\Annotation\Route;
+use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
 
 /**
  * @Route("/custom-report")
@@ -410,6 +411,14 @@ public function chartAction(Request $request)
         ]);
     }
 
+    protected function getTemporaryFileFromFileName(string $exportFileName): string {
+        $exportFileName = basename($exportFileName);
+        if(!str_ends_with($exportFileName, ".csv")) {
+            throw new InvalidArgumentException($exportFileName . " is not a valid csv file.");
+        }
+        return PIMCORE_SYSTEM_TEMP_DIRECTORY . '/' . $exportFileName;
+    }
+
     /**
      * @Route("/create-csv", name="pimcore_admin_reports_customreport_createcsv", methods={"GET"})
      *
@@ -459,7 +468,7 @@ public function createCsvAction(Request $request)
             $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/report-export-' . uniqid() . '.csv';
             @unlink($exportFile);
         } else {
-            $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY.'/'.$exportFile;
+            $exportFile = $this->getTemporaryFileFromFileName($exportFile);
         }
 
         $fp = fopen($exportFile, 'a');
@@ -497,7 +506,7 @@ public function downloadCsvAction(Request $request)
     {
         $this->checkPermission('reports');
         if ($exportFile = $request->get('exportFile')) {
-            $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/' . basename($exportFile);
+            $exportFile = $this->getTemporaryFileFromFileName($exportFile);
             $response = new BinaryFileResponse($exportFile);
             $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
             $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'export.csv');
Security advisory GHSA-g8jx-66p8-vcm2: SQL injection in pimcore/pimcore
Package: pimcore/pimcore (composer), vulnerable version: v10.0.6, fixed in: 10.0.7
CWE: CWE-89
Files changed by the fix:
bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php

Fix diff:
diff --git a/bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php b/bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php
index 0066c0fccaa..158f58f46e0 100644
--- a/bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php
+++ b/bundles/AdminBundle/Controller/Admin/DataObject/ClassificationstoreController.php
@@ -273,7 +273,7 @@ public function collectionsActionGet(Request $request)
         $storeId = $request->get('storeId');
         $storeId = $storeId ? $storeId : $storeIdFromDefinition;
 
-        $conditionParts[] = ' (storeId = ' . $storeId . ')';
+        $conditionParts[] = ' (storeId = ' . $db->quote($storeId) . ')';
 
         if ($request->get('filter')) {
             $filterString = $request->get('filter');
@@ -416,7 +416,7 @@ public function groupsActionGet(Request $request)
         }
 
         if ($request->get('storeId')) {
-            $conditionParts[] = '(storeId = ' . $request->get('storeId') . ')';
+            $conditionParts[] = '(storeId = ' . $db->quote($request->get('storeId')) . ')';
         }
 
         if ($request->get('filter')) {
Security advisory GHSA-grp3-h8m8-45p7: Glances has CQL Injection in its Cassandra Export Module via Unsanitized Config Values
Package: glances (pypi), vulnerable version: 4.5.3, fixed in: 4.5.4
CWE: CWE-89
Files changed by the fix:
glances/exports/glances_cassandra/__init__.py

Fix diff:
diff --git a/glances/exports/glances_cassandra/__init__.py b/glances/exports/glances_cassandra/__init__.py
index a9f0f5c723..b835388796 100644
--- a/glances/exports/glances_cassandra/__init__.py
+++ b/glances/exports/glances_cassandra/__init__.py
@@ -8,6 +8,7 @@
 
 """Cassandra/Scylla interface class."""
 
+import re
 import sys
 from datetime import datetime
 from numbers import Number
@@ -21,6 +22,19 @@
 from glances.logger import logger
 
 
+_CQL_IDENTIFIER_RE = re.compile(r'^[a-zA-Z][a-zA-Z0-9_]*$')
+
+
+def _validate_cql_identifier(value, name):
+    """Raise ValueError if value is not a safe CQL identifier."""
+    if not _CQL_IDENTIFIER_RE.match(str(value)):
+        raise ValueError(
+            f"Invalid CQL identifier for '{name}': {value!r}. "
+            "Only letters, digits, and underscores are allowed, and it must start with a letter."
+        )
+    return str(value)
+
+
 class Export(GlancesExport):
     """This class manages the Cassandra/Scylla export module."""
 
@@ -47,6 +61,17 @@ def __init__(self, config=None, args=None):
         if not self.export_enable:
             sys.exit(2)
 
+        # Validate CQL identifiers to prevent injection via config values
+        try:
+            self.keyspace = _validate_cql_identifier(self.keyspace, 'keyspace')
+            self.table = _validate_cql_identifier(self.table, 'table')
+            self.replication_factor = int(self.replication_factor)
+            if self.replication_factor < 1:
+                raise ValueError("replication_factor must be a positive integer")
+        except ValueError as e:
+            logger.critical(f"Cassandra configuration error: {e}")
+            sys.exit(2)
+
         # Init the Cassandra client
         self.cluster, self.session = self.init()
Security advisory GHSA-gvmf-wcx6-p974: Improper quoting of columns when using setOrderBy() or setGroupBy() on listing classes in Pimcore
Package: pimcore/pimcore (composer), vulnerable version: v10.4.3, fixed in: 10.4.4
CWE: CWE-89
Files changed by the fix:
lib/Model/Listing/AbstractListing.php

Fix diff:
diff --git a/lib/Model/Listing/AbstractListing.php b/lib/Model/Listing/AbstractListing.php
index 1683a2e2734..66a4728635f 100644
--- a/lib/Model/Listing/AbstractListing.php
+++ b/lib/Model/Listing/AbstractListing.php
@@ -235,7 +235,7 @@ public function setOrderKey($orderKey, $quote = true)
                 if ($quote === false) {
                     $this->orderKey[] = $o;
                 } elseif ($this->isValidOrderKey($o)) {
-                    $this->orderKey[] = '`' . $o . '`';
+                    $this->orderKey[] = $this->quoteIdentifier($o);
                 }
             }
         }
@@ -411,8 +411,14 @@ public function setGroupBy($groupBy, $qoute = true)
         if ($groupBy) {
             $this->groupBy = $groupBy;
 
-            if ($qoute && strpos($groupBy, '`') !== 0) {
-                $this->groupBy = '`' . $this->groupBy . '`';
+          if ($qoute) {
+                $quotedParts = [];
+                $parts = explode(",", trim($groupBy, '`'));
+                foreach($parts as $part) {
+                    $quotedParts[] = $this->quoteIdentifier(trim($part));
+                }
+
+                $this->groupBy = implode(", ", $quotedParts);
             }
         }
 
@@ -431,6 +437,13 @@ public function setValidOrders($validOrders)
         return $this;
     }
 
+    public function quoteIdentifier(string $value): string
+    {
+        $db = Db::get();
+
+        return $db->quoteIdentifier($value);
+    }
+
     /**
      * @param mixed $value
      * @param int|null $type