Sylius security release 2.0.18 / 2.1.15 / 2.2.6 — three flaws in the shop and payment API path
2 June 2026. Sylius has disclosed three security flaws and fixed them in versions 2.0.18, 2.1.15 and 2.2.6, all in the shop and payment API path. The most severe is a race condition in the cart LiveComponent through which an already completed and paid order can be altered or even deleted (CVSS 6.5); on top of that come an IDOR on the payment-request endpoints that exposes other customers' order data and lets the post-payment redirect be bent to an attacker URL, and a channel bypass in payment-method selection. All three are rated Moderate, none carries a CVE number. The fix is an ordinary upgrade to 2.0.18 / 2.1.15 / 2.2.6; for each flaw the advisory additionally provides a service-override workaround in case an immediate upgrade is not possible.
TL;DR — the 90-second summary
What was published?
A Sylius security release on 2 June 2026 with three advisories, all in the shop/payment API path: GHSA-5597-7rmh-97q5 (cart LiveComponent alters/deletes a completed order), GHSA-mr9r-h354-966r (IDOR on payment-request endpoints), GHSA-6955-hrm5-c4qp (channel bypass in payment method). Fixed in 2.0.18, 2.1.15, 2.2.6.
How severe?
Moderate. Highest single score CVSS 6.5 (GHSA-5597, integrity/data loss on paid orders), then CVSS 4.3 (channel bypass) and the IDOR (Moderate, no published score). No CVE numbers, no known active exploitation, no public PoC as of 2 June.
Which versions are affected?
All three: >=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 / 2.2.6 and above.
Am I affected?
Affected if you run a Sylius shop in one of these versions. The IDOR and the channel bypass concern the shop API (API Platform); the cart race concerns the LiveComponent frontend. Anyone using the shop API or the LiveComponents — i.e. practically every standard shop — belongs in the patch run.
Immediate mitigation?
composer update sylius/sylius to 2.0.18 / 2.1.15 / 2.2.6 (depending on your minor line), then bin/console cache:clear. If you cannot upgrade immediately: each of the three advisories provides a documented workaround via service decorator/override in src/ plus config/services.yaml.
Criticality?
See the hero badge medium. Operational patch pressure within the week; no acute exploitation situation, but three access-control/workflow defects right on the payment path are not something to leave lying around.
What happened
On 2 June 2026 Sylius published three security advisories and shipped the maintenance releases 2.0.18, 2.1.15 and 2.2.6 alongside. All three flaws sit in the same functional area: the shop frontend and the shop API around cart and payment. None of the three received a CVE number; they are tracked by their GitHub Security Advisory IDs.
The first and most severe is GHSA-5597-7rmh-97q5 (CVSS 6.5). It affects the cart FormComponent, a Symfony UX LiveComponent. The scenario: a customer has the cart page open while the order is completed in the background, e.g. because payment is finalised in another tab or the status is changed in the back office. The LiveComponent is unaware and keeps showing the old cart. If the customer now clicks „clear cart“, clearCart() calls manager->remove() on the already-completed order — the order is permanently deleted from the database. „Remove item“ and „change quantity“ mutate the completed order accordingly. The effect is irreversible loss or corruption of order data that was already binding and paid for; the path can also be triggered deliberately by an authenticated customer.
The second is GHSA-mr9r-h354-966r (IDOR, Moderate). The endpoints GET and PUT /api/v2/shop/payment-requests/{hash} look up the payment request solely by the hash from the URL, with no ownership check against the authenticated customer or the underlying order. Anyone who knows a payment-request hash can read the request and, via the payment IRI in the response, reconstruct the order's tokenValue — and thereby access the full order (items, addresses, customer email, totals). Via PUT the fields target_path and after_path can also be overwritten, the fields the frontend uses to redirect after payment; an attacker bends the redirect to their own URL. The corresponding creation endpoint POST /api/v2/shop/orders/{tokenValue}/payment-requests shares the flaw, because it too resolves the target order solely from the tokenValue.
The third is GHSA-6955-hrm5-c4qp (CVSS 4.3, channel bypass). The endpoint PATCH /api/v2/shop/account/orders/{tokenValue}/payments/{paymentId}, used by a logged-in customer to change the payment method of a placed but not-yet-paid order, does not check whether the chosen payment method is even enabled for the order's channel. The equivalent checkout endpoint correctly rejects out-of-channel payment methods with HTTP 422; the account endpoint silently accepts them with HTTP 200. A customer can thus assign any globally enabled payment method, including ones the operator deliberately excluded from that channel.
Technical assessment
The three flaws are different bug classes, but they tell the same story: a check that is missing at a second entrance even though it exists at the first. That is the recurring pattern on grown API surfaces — the checkout path is hardened, the parallel account or LiveComponent path to the same object is not.
For the channel bypass (GHSA-6955) this is literally the case: the checkout endpoint validates the payment method against the channel, the account endpoint does not. Two routes to the same state (set an order's payment method), only one carries the rule. CWE-863, Incorrect Authorization. The damage is bounded (a customer circumvents a business rule, no foreign data), but for operators with channel-specific payment-method contracts it is a real compliance and billing concern.
For the payment-request IDOR (GHSA-mr9r) the ownership check is missing entirely: the hash from the URL is the only key, with no binding to the authenticated customer or the order (CWE-639). The hash is a UUID and must be obtained out of band (logs, shared links, referrer headers), but once it is known no further credential is needed. The PUT variant lifts this beyond mere information disclosure: bending target_path/after_path lets an attacker send the buyer to a controlled page after payment — a classic open-redirect/phishing bridge right in the payment flow.
The cart race (GHSA-5597) is the most interesting, because it is not an authentication but a workflow flaw (CWE-841, Improper Enforcement of Behavioral Workflow, plus CWE-672, Operation on a Resource after Expiration). The LiveComponent implicitly assumes that an order open in the browser is still in the cart state. That assumption breaks as soon as the order is completed in parallel. The fix in the release is exactly the missing state check: hydrateResource() returns a fresh, empty cart for an order in state STATE_COMPLETED instead of mutating the completed order. Structurally it is the same lesson as with many race conditions: client-held state is an assumption, not a fact, and server-side actions must re-check the current state.
Who is affected
Affected
Not affected
Condition
Sylius 2.0.0–2.0.17, 2.1.0–2.1.14, 2.2.0–2.2.5
Sylius 2.0.18 / 2.1.15 / 2.2.6 and above
Sylius version
Shops using the shop API (API Platform) for payment requests or account order payments
Installations without an active shop API for these endpoints
Use of the affected API endpoints (GHSA-mr9r, GHSA-6955)
Shops with the standard cart LiveComponent in the frontend
Frontends that have replaced/removed the cart FormComponent
Use of the cart LiveComponent (GHSA-5597)
The fastest triage is the version (composer show sylius/sylius). Since all three flaws sit in the standard shop and API path, practically every standard Sylius shop in the affected version ranges is affected; the question is not „whether“ but „how fast“.
Impact and immediate measures
The impacts range from data loss on paid orders (cart race), through disclosure of other customers' order data including customer email and addresses (payment-request IDOR), to circumventing a business rule on the payment method (channel bypass). The IDOR disclosure is data-protection relevant: personal order data without an ownership check is a GDPR Art. 32 concern, and the bendable post-payment redirect is a phishing vector right on the payment flow. For operators under reporting duties, the availability/integrity component of the cart race is additionally an NIS-2 aspect (Art. 21).
Operational Decision Block
Act immediately if: your Sylius shop runs in an affected version range and the shop API is publicly reachable (IDOR needs no auth credential, only the hash).
In the maintenance window if: the shop API is not publicly exposed and you use the LiveComponent frontend — the patch remains mandatory, the acute lever is smaller.
Just double-check if: you run a heavily customised frontend without the standard cart LiveComponent and without the affected API endpoints — still raise the version.
In this order. First, determine the version (composer show sylius/sylius). Second, upgrade: composer update sylius/sylius to 2.0.18 / 2.1.15 / 2.2.6 (depending on your minor line), then bin/console cache:clear. Third, if an immediate upgrade is not possible, apply the workarounds from the advisories: GHSA-5597 via an override of the sylius_shop.twig.component.cart.form service with a state check in hydrateResource(); GHSA-6955 via a decorator of PaymentMethodChangerInterface that checks the payment method against the channel; GHSA-mr9r via an API Platform query extension plus state-provider decorator plus command-bus middleware that enforce ownership. Fourth, after the upgrade, verify that the out-of-channel payment method now returns 422 on the account endpoint and that the payment-request endpoint returns 404 for foreign hashes.
This article reflects my technical and strategic assessment. It is not legal advice and not a data-protection impact assessment.
Detection / verification
Lead. The primary question is the version; detecting past exploitation is hard because the accesses look like regular API calls. The focus is on version triage and targeted log review of the affected endpoints.
Check snippets (copy/paste):
# 1) Determine the installed Sylius version
composer show sylius/sylius | grep -i versions
# 2) Raise to the fix versions (depending on your minor line)
composer require "sylius/sylius:^2.2.6" # or ^2.1.15 / ^2.0.18
bin/console cache:clear
# 3) Review access to the payment-request endpoints (IDOR suspicion)
# Many GET/PUT on different hashes from one source = suspicious
grep -E "/api/v2/shop/payment-requests/" var/log/*.log access.log 2>/dev/null
# 4) Check account-order-payment PATCH for out-of-channel methods
grep -E "PATCH .*/api/v2/shop/account/orders/.*/payments/" access.log 2>/dev/null
What is suspicious: one source querying many payment-request hashes in sequence (IDOR enumeration), PUT requests on payment requests that set target_path/after_path to external domains, and successful PATCH payment-method changes via the account endpoint to methods not offered in the respective channel. For the cart race the warning sign is rather in the data: completed orders that still show mutation or deletion events after their finalisation.
Operator recommendation
German Mittelstand
For most Sylius shops this is an ordinary minor update within your own 2.x line: composer update sylius/sylius, clear the cache, deploy, test briefly. Sylius maintains 2.0, 2.1 and 2.2 in parallel, so the upgrade stays in the familiar line without breaking changes. If you have a maintenance contract, have the patch applied in the regular security window; if you expose the shop API publicly, bring it forward.
Shop operation & customisations
Anyone who has built heavily customised LiveComponents or own API resources should check after the upgrade whether their extensions inherit or bypass the new state and ownership checks. Especially with an overridden cart FormComponent: the new STATE_COMPLETED check in hydrateResource() must reach your own variant, otherwise the race condition stays open.
Containers / deployment
For containerised shops the version bump belongs in the image (composer update in the build), not in the running container; redeploy afterwards. The composer.lock is the source of truth — after the upgrade, verify that the pinned version is actually 2.0.18 / 2.1.15 / 2.2.6 or higher.
Frequently asked questions about the Sylius security release 2.0.18 / 2.1.15 / 2.2.6
Can a customer really delete an already-paid order?+
Yes, under the conditions of GHSA-5597: the cart page stays open while the order is completed, then „clear cart“ triggers a remove() on the completed order. This can happen accidentally (two tabs) or deliberately. 2.0.18 / 2.1.15 / 2.2.6 checks the STATE_COMPLETED state and returns a fresh cart instead.
How dangerous is the bendable redirect in the payment request?+
Via PUT on the payment request, target_path/after_path can be set, which serve as the redirect after payment. An attacker with the hash can thus send the buyer to their own page after payment — a phishing vector in the payment flow. The precondition is possession of the payment-request hash (UUID), which must be obtained out of band.
Am I affected if I don't use the Sylius shop API at all?+
The payment-request IDOR and the channel bypass concern the shop API endpoints — without using them, that part is not reachable. The cart race (GHSA-5597), by contrast, concerns the standard cart LiveComponent in the frontend, i.e. classic, non-headless shops too. You should upgrade in any case.
I can't upgrade immediately — what now?+
Each of the three advisories contains a complete workaround via service override in src/ plus config/services.yaml (cart FormComponent override, PaymentMethodChanger decorator, API Platform ownership extension/provider/middleware). These close the respective path without upgrading; the upgrade remains the clean long-term solution.
Are there CVE numbers for these flaws?+
No. All three run only under their GitHub Security Advisory IDs (GHSA-5597-7rmh-97q5, GHSA-mr9r-h354-966r, GHSA-6955-hrm5-c4qp). That changes nothing about handling them: the GHSA IDs are the authoritative reference, and the fix is the same upgrade.
Which Sylius version do I need to close all three flaws?+
2.0.18, 2.1.15 or 2.2.6 (depending on your minor line) or higher. All three advisories are fixed by exactly these releases — a single update closes all three.
Conclusion
The Sylius release of 2 June 2026 is no fire alarm, but three access-control and workflow defects right on the payment path are not something to leave lying around. The sober assessment: Moderate, no CVEs, no known active exploitation, no public PoC, but the highest of the three (CVSS 6.5) leads to irreversible loss of paid order data, and the IDOR discloses personal data without any credential once a hash is known. The measure is pleasantly simple: a minor update within your own 2.x line to 2.0.18 / 2.1.15 / 2.2.6, clear the cache, done; whoever cannot do so immediately has a documented override for each flaw. The recurring lesson for your own shop customisations remains: the same check belongs at every door to the same object — hardening the checkout path and forgetting the account or LiveComponent path is exactly the gap that occurred three times here.
Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.