From ff36431819e4544fc040d10203b02e94fb790603 Mon Sep 17 00:00:00 2001 From: kaioken Date: Mon, 14 Jun 2021 13:40:19 -0400 Subject: [PATCH 1/2] hotfix sql injection --- src/QueryParserCustomFields.php | 53 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/QueryParserCustomFields.php b/src/QueryParserCustomFields.php index c90f73e..505b511 100755 --- a/src/QueryParserCustomFields.php +++ b/src/QueryParserCustomFields.php @@ -169,22 +169,61 @@ public function request() : array $sort = ''; if (array_key_exists('sort', $this->request)) { $sort = $this->request['sort']; + $columnsData = $this->getTableColumns(); - if (!empty($sort)) { + if (!empty($sort) && strpos($sort, '|') !== false) { // Get the model, column and sort order from the sent parameter. - $modelColumn = $sort; - if (strpos($sort, '|') !== false) { - list($modelColumn, $order) = explode('|', $sort); - } + list($modelColumn, $order) = explode('|', $sort); $order = strtolower($order) === 'asc' ? 'ASC' : 'DESC'; $modelColumn = preg_replace("/[^a-zA-Z0-9_\s]/", '', $modelColumn); - $columnsData = $this->getTableColumns(); + // Check to see whether this is a related sorting by looking for a if (isset($columnsData[$modelColumn])) { - $sort = " ORDER BY {$modelColumn} {$order}"; + if (strpos($modelColumn, '.') !== false) { + // We are using a related sort. + // Get the namespace for the models from the configuration. + $modelNamespace = \Phalcon\Di::getDefault()->getConfig()->namespace->models; + // Get the model name and the sort column from the sent parameter + list($model, $column) = explode('.', $modelColumn); + // Convert the model name into camel case. + $modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model))); + // Create the model name with the appended namespace. + $modelName = $modelNamespace . '\\' . $modelName; + + // Make sure the model exists. + if (!class_exists($modelName)) { + throw new \Exception('Related model does not exist.'); + } + + // Instance the model so we have access to the getSource() function. + $modelObject = new $modelName(); + // Instance meta data memory to access the primary keys for the table. + $metaData = new \Phalcon\Mvc\Model\MetaData\Memory(); + // Get the first matching primary key. + // @TODO This will hurt on compound primary keys. + $primaryKey = $metaData->getPrimaryKeyAttributes($modelObject)[0]; + if ($metaData->hasAttribute($modelObject, $column)) { + // We need the table to exist in the query in order for the related sort to work. + // Therefore we add it to comply with this by comparing the primary key to not being NULL. + $this->relationSearchFields[$modelName][] = [ + $primaryKey, ':', '$$', + ]; + + $sort = " ORDER BY {$modelObject->getSource()}.{$column} {$order}"; + } + unset($modelObject); + } else { + $sort = " ORDER BY {$modelColumn} {$order}"; + } } else { $sort = ''; } + } else { + if (isset($columnsData[$sort])) { + $sort = " ORDER BY {$sort} DESC"; + } else { + $sort = null; + } } } From 5b3f7734308e3abeeda0a9cecadb14565a83d05b Mon Sep 17 00:00:00 2001 From: kaioken Date: Mon, 14 Jun 2021 13:44:09 -0400 Subject: [PATCH 2/2] update injection --- src/QueryParserCustomFields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QueryParserCustomFields.php b/src/QueryParserCustomFields.php index 505b511..920f788 100755 --- a/src/QueryParserCustomFields.php +++ b/src/QueryParserCustomFields.php @@ -216,7 +216,7 @@ public function request() : array $sort = " ORDER BY {$modelColumn} {$order}"; } } else { - $sort = ''; + $sort = null; } } else { if (isset($columnsData[$sort])) {