CVE-2026-31825: Sylius has a DQL Injection via API Order Filters
Impact Sylius API filters ProductPriceOrderFilter and TranslationOrderNameAndLocaleFilter pass user-supplied order direction values directly to Doctrine's orderBy() without validation. An attacker can inject arbitrary DQL:
GET /api/v2/shop/products?order[price]=ASC,%20variant.code%20DESC
Patches The issue is fixed in versions: 1.9.12, 1.10.16, 1.11.17, 1.12.23, 1.13.15, 1.14.18, 2.0.16, 2.1.12, 2.2.3 and above.
Workarounds
An EventSubscriber that sanitizes order query parameters only on API routes before they reach the vulnerable filters.
The subscriber accepts an $apiRoute constructor parameter (default /api/v2) and skips non-API requests entirely — so there is zero overhead on shop/admin page requests.
This follows the same pattern used by Sylius's own KernelRequestEventSubscriber (src/Sylius/Bundle/ApiBundle/EventSubscriber/KernelRequestEventSubscriber.php), which also uses strcontains($pathInfo, $this->apiRoute) to scope logic to API routes.
---
Step 1 — Create the EventSubscriber
src/EventSubscriber/SanitizeOrderDirectionSubscriber.php:
php <?php
declare(stricttypes=1);
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents;
final class SanitizeOrderDirectionSubscriber implements EventSubscriberInterface { private const ALLOWEDDIRECTIONS = ['asc', 'desc'];
public function construct( private string $apiRoute, ) { }
public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => ['sanitizeOrderParameters', 64], ]; }
public function sanitizeOrderParameters(RequestEvent $event): void { if (!strcontains($event->getRequest()->getPathInfo(), $this->apiRoute)) { return; }
$request = $event->getRequest();
/ @var mixed $order / $order = $request->query->all()['order'] ?? null; if (!isarray($order)) { return; }
$needsSanitization = false; $sanitized = []; foreach ($order as $field => $direction) { if (isstring($direction) && inarray(strtolower($direction), self::ALLOWEDDIRECTIONS, true)) { $sanitized[$field] = $direction; } else { $needsSanitization = true; } }
if (!$needsSanitization) { return; }
$all = $request->query->all(); $all['order'] = $sanitized; $request->query->replace($all);
$request->server->set('QUERYSTRING', httpbuildquery($all)); $request->attributes->set('apifilters', $all); } }
Step 2 — Register the service
Option A — If your config/services.yaml already has App\ autowiring (Symfony default):
yaml Nothing to do — autoconfigure picks up EventSubscriberInterface automatically. Optionally bind the API route prefix: services: App\EventSubscriber\SanitizeOrderDirectionSubscriber: arguments: $apiRoute: '%sylius.security.newapiroute%'
Option B — If there is no App\ autowiring:
yaml services: App\EventSubscriber\SanitizeOrderDirectionSubscriber: arguments: $apiRoute: '%sylius.security.newapiroute%' tags: ['kernel.eventsubscriber']
Using %sylius.security.newapiroute% ties the subscriber to the same prefix Sylius uses (/api/v2 by default). If the parameter is not available, hardcode '/api/v2' instead.
Step 3 — Clear cache
bash bin/console cache:clear
Reporters
We would like to extend our gratitude to the following individuals for their detailed reporting and responsible disclosure of this vulnerability: - Chris Alupului (@Neosprings) - Bartłomiej Nowiński (@bnBart)
For more information If you have any questions or comments about this advisory:
- Open an issue in Sylius issues - Email us at security@sylius.com
Other sources
Sylius is an Open Source eCommerce Framework on Symfony. Sylius API filters ProductPriceOrderFilter and TranslationOrderNameAndLocaleFilter pass user-supplied order direction values directly to Doctrine's orderBy() without validation. An attacker can inject arbitrary DQL. The issue is fixed in versions: 1.9.12, 1.10.16, 1.11.17, 1.12.23, 1.13.15, 1.14.18, 2.0.16, 2.1.12, 2.2.3 and above.
— MITRE
Affected Software
Event History
Frequently Asked Questions
What is the severity of CVE-2026-31825?
CVE-2026-31825 has been classified as a critical vulnerability due to the potential for DQL Injection.
How do I fix CVE-2026-31825?
To fix CVE-2026-31825, update Sylius to version 1.9.12 or later, as earlier versions are vulnerable.
What are the affected versions in CVE-2026-31825?
CVE-2026-31825 affects Sylius versions up to 1.9.12, 1.10.16, 1.11.17, 1.12.23, 1.13.15, 1.14.18, 2.0.16, 2.1.12, and 2.2.3.
What kind of attack can be executed using CVE-2026-31825?
An attacker can exploit CVE-2026-31825 to execute DQL Injection attacks through the API Order Filters.
Is CVE-2026-31825 related to specific Sylius components?
Yes, CVE-2026-31825 specifically affects the ProductPriceOrderFilter and TranslationOrderNameAndLocaleFilter in Sylius.