CVE-2026-53637: Sylius Cart FormComponent Vulnerability Leading to Order Data Corruption
Summary
CVE-2026-53637: Sylius: Cart FormComponent allows modification or deletion of an already-completed order. Affects sylius/sylius across 3 version ranges.
>= 2.0.0, < 2.0.18
>= 2.1.0, < 2.1.15
>= 2.2.0, < 2.2.6
Fixed in 2.0.18, 2.1.15 or 2.2.6, depending on the release line you run. How to fix ↓
Check if this vulnerability affects your application
Upload a manifest or SBOM and we'll show whether you're affected, plus every other risky package in the same scan.
No signup required · Results in about 60 seconds
Background
Sylius is an open-source eCommerce platform built on Symfony, designed to provide a flexible and customizable solution for online stores. It offers features such as product management, order processing, and customer management. The Cart FormComponent is responsible for managing the shopping cart's state and user interactions. However, it is vulnerable to a flaw that allows users to modify or delete completed orders, compromising the integrity of order data.
Vulnerability Detail
The vulnerability arises when a user keeps the cart page open while an order is completed in another tab. The cart page does not reflect the updated order state, allowing the user to clear the cart, remove products, or change quantities on an already completed order. This can lead to irreversible data corruption or loss of order information, even after payment has been finalized. The flaw can be exploited by authenticated users, potentially leading to unauthorized modifications of their orders.
How To Fix
Fixed versions by release line
The minimum fixed version depends on the release line you run.
-
>= 2.0.0, < 2.0.182.0.18composer require sylius/sylius:2.0.18 -
>= 2.1.0, < 2.1.152.1.15composer require sylius/sylius:2.1.15 -
>= 2.2.0, < 2.2.62.2.6composer require sylius/sylius:2.2.6
Tip — Not sure which release line you're on? Vulert can find the fix for the version you are using. Scan free →
Workaround
If immediate updating is not possible, create a patched copy of the affected class in your application's src directory and override the Sylius service definition. Follow these steps:
- Create src/Twig/Component/Cart/FormComponent.php with the following code:
<?php
declare(strict_types=1);
namespace App\Twig\Component\Cart;
use Doctrine\Persistence\ObjectManager;
use Sylius\Bundle\UiBundle\Twig\Component\ResourceFormComponentTrait;
use Sylius\Bundle\UiBundle\Twig\Component\TemplatePropTrait;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderCheckoutStates;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Order\SyliusCartEvents;
use Sylius\Resource\Model\ResourceInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\Attribute\PreReRender;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
class FormComponent
{
use ComponentToolsTrait;
use ResourceFormComponentTrait;
use TemplatePropTrait;
public const SYLIUS_SHOP_CART_CHANGED = 'sylius:shop:cart_changed';
public const SYLIUS_SHOP_CART_CLEARED = 'sylius:shop:cart_cleared';
public bool $shouldSaveCart = true;
public function __construct(
OrderRepositoryInterface $orderRepository,
FormFactoryInterface $formFactory,
string $resourceClass,
string $formClass,
protected readonly ObjectManager $manager,
protected readonly EventDispatcherInterface $eventDispatcher,
) {
$this->initialize($orderRepository, $formFactory, $resourceClass, $formClass);
}
public function hydrateResource(mixed $value): ?ResourceInterface
{
if (empty($value)) {
return $this->createResource();
}
$order = $this->repository->find($value);
if (!$order instanceof OrderInterface || $order->getCheckoutState() === OrderCheckoutStates::STATE_COMPLETED) {
return $this->createResource();
}
return $order;
}
#[PreReRender(priority: -100)]
public function saveCart(): void
{
if ($this->shouldSaveCart && $this->resource?->getId() !== null) {
$form = $this->getForm();
if ($form->isValid()) {
$this->eventDispatcher->dispatch(new GenericEvent($form->getData()), SyliusCartEvents::CART_CHANGE);
$this->manager->flush();
$this->emit(self::SYLIUS_SHOP_CART_CHANGED, ['cartId' => $this->resource->getId()]);
}
}
}
#[LiveAction]
public function removeItem(#[LiveArg] int $index): void
{
if ($this->resource?->getId() === null) {
return;
}
$data = $this->formValues['items'];
unset($data[$index]);
$this->formValues['items'] = array_values($data);
$orderItem = $this->resource->getItems()->get($index);
$this->eventDispatcher->dispatch(new GenericEvent($orderItem), SyliusCartEvents::CART_ITEM_REMOVE);
$this->manager->persist($this->resource);
$this->manager->flush();
$this->manager->refresh($this->resource);
$this->shouldSaveCart = false;
$this->submitForm();
$this->emit(self::SYLIUS_SHOP_CART_CHANGED, ['cartId' => $this->resource->getId()]);
}
#[LiveAction]
public function clearCart(): void
{
if ($this->resource?->getId() === null) {
return;
}
$this->formValues['items'] = [];
$this->eventDispatcher->dispatch(new GenericEvent($this->resource), SyliusCartEvents::CART_CLEAR);
$this->manager->remove($this->resource);
$this->manager->flush();
$this->resource = $this->createResource();
$this->resetForm();
$this->isValidated = false;
$this->validatedFields = [];
$this->shouldSaveCart = false;
$this->submitForm();
$this->emit(self::SYLIUS_SHOP_CART_CLEARED);
}
#[LiveAction]
public function removeCoupon(): void
{
$this->formValues['promotionCoupon'] = '';
$this->submitForm();
}
private function getDataModelValue(): string
{
return 'debounce(500)|*';
}
}
- Override the Sylius service in config/services.yaml:
services:
sylius_shop.twig.component.cart.form:
class: App\Twig\Component\Cart\FormComponent
arguments:
- '@sylius.repository.order'
- '@form.factory'
- '%sylius.model.order.class%'
- 'Sylius\Bundle\ShopBundle\Form\Type\CartType'
- '@doctrine.orm.entity_manager'
- '@event_dispatcher'
calls:
- [setLiveResponder, ['@ux.live_component.live_responder']]
tags:
- { name: sylius.live_component.shop, key: 'sylius_shop:cart:form' }
- Clear the cache:
bin/console cache:clear
Conclusion
The CVE-2026-53637 vulnerability in Sylius poses a significant risk to order integrity, allowing unauthorized modifications to completed orders. It is crucial to update to the patched versions or implement the provided workaround to mitigate this risk.
See every vulnerability recorded for sylius/sylius →
FAQ
It is a vulnerability in the Sylius Cart FormComponent that allows users to modify or delete completed orders.
You can check your application for this vulnerability using Vulert, which monitors open-source vulnerabilities in real-time.
Exploiting this vulnerability can lead to irreversible data corruption or loss of order information for completed transactions.
You can update Sylius to the patched version using Composer with the command: composer update sylius/sylius.
You can implement a workaround by creating a patched copy of the affected class and overriding the service definition.
References
Related vulnerabilities
Recent vulnerabilities recorded for sylius/sylius.