Skip to content

Instantly share code, notes, and snippets.

@lchrusciel
Created March 15, 2022 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lchrusciel/5c2f134c28df6f18feef47a5343f2a73 to your computer and use it in GitHub Desktop.
Save lchrusciel/5c2f134c28df6f18feef47a5343f2a73 to your computer and use it in GitHub Desktop.
DQL injection through sorting parameters security bug fix
# config/services.yaml
services:
# ...
sylius.grid.sorter:
class: App\Sorting\Sorter
<?php
// src/App/Sorting/Sorter.php
declare(strict_types=1);
namespace App\Sorting;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Sylius\Component\Grid\Data\DataSourceInterface;
use Sylius\Component\Grid\Definition\Grid;
use Sylius\Component\Grid\Parameters;
use Sylius\Component\Grid\Sorting\SorterInterface;
final class Sorter implements SorterInterface
{
public function sort(DataSourceInterface $dataSource, Grid $grid, Parameters $parameters): void
{
$enabledFields = $grid->getFields();
$expressionBuilder = $dataSource->getExpressionBuilder();
$sorting = $parameters->get('sorting', $grid->getSorting());
$this->validateSortingParams($sorting, $enabledFields);
foreach ($sorting as $field => $order) {
$this->validateFieldNames($field, $enabledFields);
$gridField = $grid->getField($field);
$property = $gridField->getSortable();
if (null !== $property) {
$expressionBuilder->addOrderBy($property, $order);
}
}
}
private function validateSortingParams(array $sorting, array $enabledFields): void
{
foreach (array_keys($enabledFields) as $key) {
if (array_key_exists($key, $sorting) && !in_array($sorting[$key], ['asc', 'desc'])) {
throw new BadRequestHttpException(sprintf('%s is not valid, use asc or desc instead.', $sorting[$key]));
}
}
}
private function validateFieldNames(string $fieldName, array $enabledFields): void
{
$enabledFieldsNames = array_keys($enabledFields);
if (!in_array($fieldName, $enabledFieldsNames, true)) {
throw new BadRequestHttpException(sprintf('%s is not valid field, did you mean one of these: %s?', $fieldName, implode(', ', $enabledFieldsNames)));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment