GitHub Security Advisory: GHSA-2xc6-348p-c2x6
Package: sylius/sylius (COMPOSER)
Severity: HIGH (CVSS 0.0)
CWE: CWE-639: Authorization Bypass Through User-Controlled Key
Vulnerable versions: >= 2.0.0, <= 2.0.15
Patched in: 2.0.16

Summary: Sylius affected by IDOR in Cart and Checkout LiveComponents

Details:
### Impact
An authenticated Insecure Direct Object Reference (IDOR) vulnerability exists in multiple shop LiveComponents due to unvalidated resource IDs accepted via `#[LiveArg]` parameters. Unlike props, which are protected by LiveComponent's `@checksum`, `args` are fully user-controlled - any action that accepts a resource ID via `#[LiveArg]` and loads it with `->find()` without ownership validation is vulnerable.

Checkout address **FormComponent** (`addressFieldUpdated` action): Accepts an `addressId` via `#[LiveArg]` and loads it without verifying ownership, exposing another user's first name, last name, company, phone number, street, city, postcode, and country.

Cart **WidgetComponent** (`refreshCart` action): Accepts a `cartId` via `#[LiveArg]` and loads any order directly from the repository, exposing order total and item count.

Cart **SummaryComponent** (`refreshCart` action): Accepts a `cartId` via `#[LiveArg]` and loads any order directly from the repository, exposing subtotal, discount, shipping cost, taxes (excluded and included), and order total.

Since `sylius_order` contains both active carts (`state=cart`) and completed orders (`state=new/fulfilled`) in the same ID space, the cart IDOR exposes data from all orders, not just active carts.

### Patches
The issue is fixed in versions: 2.0.16, 2.1.12, 2.2.3 and above.

### Workarounds

Override vulnerable LiveComponent classes at the project level to add authorization checks to `#[LiveArg]` parameters.

#### Step 1. Exclude component overrides from default autowiring

In `config/services.yaml`, add `Twig/Component` to the exclude list to prevent duplicate service registration:

```yaml
App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Kernel.php,Twig/Components}'
```

#### Step 2. Override checkout address FormComponent

Create `src/Twig/Components/Checkout/Address/FormComponent.php`:

```php
<?php

declare(strict_types=1);

namespace App\Twig\Components\Checkout\Address;

use Sylius\Bundle\ShopBundle\Twig\Component\Checkout\Address\AddressBookComponent;
use Sylius\Bundle\UiBundle\Twig\Component\ResourceFormComponentTrait;
use Sylius\Bundle\UiBundle\Twig\Component\TemplatePropTrait;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Core\Repository\AddressRepositoryInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Customer\Context\CustomerContextInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\Attribute\LiveListener;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\Attribute\PreReRender;

#[AsLiveComponent]
class FormComponent
{
    /** @use ResourceFormComponentTrait<OrderInterface> */