Skip to content

Commit

Permalink
Merge pull request #44 from bakaphp/hotfix-sort-injection
Browse files Browse the repository at this point in the history
  • Loading branch information
kaioken authored Jun 15, 2021
2 parents 5ea7d96 + 5b3f773 commit 3823445
Showing 1 changed file with 47 additions and 8 deletions.
55 changes: 47 additions & 8 deletions src/QueryParserCustomFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,60 @@ 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 = null;
}
} else {
if (isset($columnsData[$sort])) {
$sort = " ORDER BY {$sort} DESC";
} else {
$sort = '';
$sort = null;
}
}
}
Expand Down

0 comments on commit 3823445

Please sign in to comment.