NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐘 Packagist
Not in CISA KEV

Sylius has a XSS vulnerability in checkout login formGHSA-vgh8-c6fp-7gcg

GHSA-vgh8-c6fp-7gcg is a Cross-site Scripting (XSS) vulnerability in sylius/sylius. A fix is available for sylius/sylius — see the affected versions and patch details below.

Also known asCVE-2026-31822
Published
Updated
Affected
3 pkgs
Patched
3 / 3
Exploits
None indexed
Exploitation data as of Nov 9, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-vgh8-c6fp-7gcg.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk+0.02%
Lower risk than most CVEs12th percentile — riskier than 12% of all scored CVEsHighest risk
0.00%0.26%0.53%0.79%0.0%0.2%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

3 pkgs affected
🐘sylius/sylius🐘sylius/sylius🐘sylius/sylius

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Impact

A cross-site scripting (XSS) vulnerability exists in the shop checkout login form handled by the ApiLoginController Stimulus controller.

When a login attempt fails, AuthenticationFailureHandler returns a JSON response whose message field is rendered into the DOM using innerHTML, allowing any HTML or JavaScript in that value to be parsed and executed by the browser.

The message value originates from AuthenticationException::getMessageKey() passed through Symfony's translator (security domain, using the request locale). In the default Sylius installation, this returns a hardcoded translation key (e.g. "Invalid credentials."), which is not directly user-controlled. However, using innerHTML with server-derived data violates defense-in-depth principles, and the risk escalates significantly under realistic scenarios:

  • Customized authentication handlers — if a project overrides AuthenticationFailureHandler to include user-supplied data in the message (e.g. "No account found for <username>"), an attacker can inject arbitrary JavaScript directly via the login form without any privileged access.
  • Translation injection — if translation files are sourced from an untrusted database or CMS and contain HTML, the message could carry a malicious payload.
  • Man-in-the-Middle — if the response is intercepted (e.g. on HTTP or via a compromised proxy), an attacker can inject arbitrary HTML/JS into the message field.
  • Server-side injection — if any middleware, reverse proxy, or error handler modifies the JSON response body, malicious content could be injected into the message field.

Exploitation could lead to session hijacking, credential theft, cart/order manipulation, or phishing within the trusted shop domain.

The vulnerability affects all Sylius installations that use the default shop checkout login form with the bundled ApiLoginController.js.

Patches

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

Workarounds

Override the vulnerable JavaScript controller at the project level.

Note: Step 2 differs between Sylius 2.0 and up

Step 1. Override JavaScript controller handling login

Patch ApiLoginController.js

Copy the original from vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/assets/controllers/ApiLoginController.js to assets/shop/controllers/ApiLoginController.js and apply:

...
  .then(response => {
    if (response.success) {
      window.location.reload();
    } else {
      const errorElement = this.errorPrototypeTarget.cloneNode(true);
-     errorElement.innerHtml = response.message;
+     errorElement.textContent = response.message;
      this.errorTarget.innerHTML = errorElement.outerHTML;
    }
  })
...

Step 2. Register the patched controller

Sylius 2.1+ (Stimulus Bridge with controllers.json)

Disable the vendor controller in assets/shop/controllers.json:

...
  "api-login": {
-    "enabled": true,
+    "enabled": false,
    "fetch": "lazy"
  }
...

Register the overwritten controller in assets/shop/bootstrap.js

import ApiLoginController from './controllers/ApiLoginController'

app.register('sylius--shop-bundle--api-login', ApiLoginController);

Sylius 2.0 (explicit imports in vendor app.js)

Use Webpack's NormalModuleReplacementPlugin to swap the controller at build time. In webpack.config.js, after shopConfig is created:

+ const webpack = require('webpack');
...
  // Shop config
  const shopConfig = SyliusShop.getWebpackConfig(path.resolve(__dirname));
+ shopConfig.plugins.push(
+   new webpack.NormalModuleReplacementPlugin(
+     /\/controllers\/ApiLoginController\.js$/,
+     path.resolve(__dirname, 'assets/shop/controllers/ApiLoginController.js')
+   )
+ );
...

Step 3. Rebuild assets

yarn encore dev  # or: yarn encore production

Reporters

We would like to extend our gratitude to the following individuals for their detailed reporting and responsible disclosure of this vulnerability:

  • Bartłomiej Nowiński (@bnBart)

For more information

If you have any questions or comments about this advisory:

Affected Packages

3 total 3 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistsylius/sylius≥ 2.0.0&&< 2.0.162.0.16composer require sylius/sylius:^2.0.16
🐘Packagistsylius/sylius≥ 2.1.0&&< 2.1.122.1.12composer require sylius/sylius:^2.1.12
🐘Packagistsylius/sylius≥ 2.2.0&&< 2.2.32.2.3composer require sylius/sylius:^2.2.3

Affected Products

1 product · 3 configurations
Application
syliussylius
≥ 2.2.0 && < 2.2.3
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for sylius/sylius, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update sylius/sylius to 2.0.16 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-vgh8-c6fp-7gcg is resolved across your whole dependency graph.

  3. Workarounds

    Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page.

Frequently Asked Questions

### Impact A cross-site scripting (XSS) vulnerability exists in the shop checkout login form handled by the ApiLoginController Stimulus controller. When a login attempt fails, AuthenticationFailureHandler returns a JSON response whose message field is rendered into the DOM using innerHTML, allowing any HTML or JavaScript in that value to be parsed and executed by the browser. The message value originates from `AuthenticationException::getMessageKey()` passed through Symfony's trans
O3 Security · Impact-Aware SCA

Is GHSA-vgh8-c6fp-7gcg in your dependencies?

Find it across Packagist, including transitive dependencies.

Sylius has a XSS vulnerability in checkout login form