VDB
EN
MEDIUM 4.3

GHSA-6955-hrm5-c4qp

Sylius: Channel-based payment method restriction bypass on shop account orders API endpoint

상세

### Impact An authorization bypass vulnerability exists in the shop account API. The `PATCH /api/v2/shop/account/orders/{tokenValue}/payments/{paymentId}` endpoint, used by an authenticated shop customer to change the payment method of an order that has been placed but not yet paid (state `STATE_NEW`), does not validate that the chosen payment method is enabled for the order's channel. The equivalent checkout endpoint (`PATCH /api/v2/shop/orders/{tokenValue}/payments/{paymentId}`) correctly rejects out-of-channel payment methods with `HTTP 422`; the account endpoint silently accepts them and returns `HTTP 200`.

An authenticated customer can therefore assign any globally enabled payment method to their own placed order, including methods that the store operator has explicitly excluded from that channel.

### Patches The issue is fixed in versions: 2.0.18, 2.1.15, 2.2.6 and above.

### Workarounds If users cannot bump Sylius right now, decorate the `Sylius\Bundle\ApiBundle\Changer\PaymentMethodChangerInterface` service in their applications.

#### Step 1. Create the decorator

`src/Decorator/ChannelCheckingPaymentMethodChanger.php`:

```php <?php

declare(strict_types=1);

namespace App\Decorator;

use ApiPlatform\Validator\Exception\ValidationException; use Sylius\Bundle\ApiBundle\Changer\PaymentMethodChangerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\PaymentMethodInterface; use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface; use Sylius\Component\Core\Repository\PaymentRepositoryInterface; use Sylius\Component\Payment\Resolver\PaymentMethodsResolverInterface; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Contracts\Translation\TranslatorInterface;

final readonly class ChannelCheckingPaymentMethodChanger implements PaymentMethodChangerInterface { public function __construct( private PaymentMethodChangerInterface $decorated, private PaymentRepositoryInterface $paymentRepository, private PaymentMethodRepositoryInterface $paymentMethodRepository, private PaymentMethodsResolverInterface $paymentMethodsResolver, private TranslatorInterface $translator, ) { }

public function changePaymentMethod(string $paymentMethodCode, mixed $paymentId, OrderInterface $order): OrderInterface { /** @var PaymentMethodInterface|null $paymentMethod */ $paymentMethod = $this->paymentMethodRepository->findOneBy(['code' => $paymentMethodCode]); $payment = $this->paymentRepository->findOneByOrderId($paymentId, $order->getId());

if ( $paymentMethod !== null && $payment !== null && !in_array($paymentMethod, $this->paymentMethodsResolver->getSupportedMethods($payment), true) ) { $template = 'sylius.payment_method.not_available'; $parameters = ['%name%' => (string) $paymentMethod->getName()];

throw new ValidationException(new ConstraintViolationList([ new ConstraintViolation( message: $this->translator->trans($template, $parameters, 'validators'), messageTemplate: $template, parameters: $parameters, root: $paymentMethodCode, propertyPath: '', invalidValue: $paymentMethodCode, ), ])); }

return $this->decorated->changePaymentMethod($paymentMethodCode, $paymentId, $order); } } ```

#### Step 2. Register the decorator

`config/services.yaml` (append to the application's existing `services:` block):

```yaml services: App\Decorator\ChannelCheckingPaymentMethodChanger: decorates: sylius_api.changer.payment_method arguments: - '@.inner' - '@sylius.repository.payment' - '@sylius.repository.payment_method' - '@sylius.resolver.payment_methods' - '@translator' ```

`@.inner` references the original `PaymentMethodChangerInterface` implementation, so any future Sylius change to the changer keeps working through the decorator.

#### Step 3. Clear the 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: - Fredrik Dietrichson (@FredrikEV)

### For more information

If there are any questions or comments about this advisory:

- Open an issue in [Sylius issues](https://github.com/Sylius/Sylius/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen) - Send an email to [security@sylius.com](mailto:security@sylius.com)

이 버전이 영향받나요?

사용 중인 패키지 버전을 입력하면 즉시 평가합니다.

영향 패키지

Packagist / sylius/sylius
최초 영향 버전: 2.0.0 수정 버전: 2.0.18
수정 composer require sylius/sylius:^2.0.18
Packagist / sylius/sylius
최초 영향 버전: 2.1.0 수정 버전: 2.1.15
수정 composer require sylius/sylius:^2.1.15
Packagist / sylius/sylius
최초 영향 버전: 2.2.0 수정 버전: 2.2.6
수정 composer require sylius/sylius:^2.2.6

참고