All posts
Forward Development

Vendure 3.7 security advisories: why patching to 3.6.x is not enough

Vendure 3.7.0 fixes five advisories, including a critical account takeover never backported to 3.6.x. Who is exposed, and what the upgrade actually costs.

  • Vendure
  • Operations
  • Migrations

You run a Vendure storefront, you see "security fixes" in a release note, and you have to decide tonight whether that means patch on the next sprint or patch before you go to bed.

Here is the part that decides it. Vendure 3.7.0 addresses five advisories. Four were also backported to the latest 3.6.x line. One was not: a critical external-authentication account takeover, fixed in 3.7.0 only. If you patch to the newest 3.6.x and stop there, you have closed four holes and left the most severe one open.

That distinction is the whole article. The rest is which ones actually apply to you, and what the 3.7 upgrade costs — because it is not a drop-in bump.

The five advisories, and where each is fixed

SeverityIssueFixed in
CriticalExternal/SSO login could link to an existing account by email without verification — account takeover3.7.0 only
HighStored XSS in the dashboard via unsafe HTML-stripping of entity descriptions3.7.0 and latest 3.6.x
HighUnauthenticated ReDoS via the regex filter on SQLite backends3.7.0 and latest 3.6.x
HighFile-upload type bypass — uploads trusted the Content-Type header without verifying contents3.7.0 and latest 3.6.x
ModerateShop API list queries could return non-public entities when filterOperator was OR3.7.0 and latest 3.6.x

The current release at the time of writing is 3.7.1. If you are going to move, move to that.

The critical one: external-auth account takeover

If you offer social or SSO login — Google, an enterprise IdP, anything implementing AuthenticationStrategy — an external login could be linked to a pre-existing local account purely on a matching email address, without that email having been verified by the provider. An attacker who can obtain a token asserting a victim's email address gets that victim's account, orders, addresses, and saved payment references.

Who is exposed: anyone running external authentication on 3.6.x, including the newest 3.6.x. This is the advisory that makes "just patch the 3.6 line" the wrong answer. If you do not offer external login at all, this one does not apply to you — and if that is your situation, staying on 3.6.x is defensible for a little longer.

The unauthenticated DoS on SQLite instances

Unauthenticated means no login and no valid customer session — a crafted request against the public API is enough. It only bites instances using SQLite as the production datastore, via a ReDoS in the regex filter. SQLite is single-writer with whole-file locking, so a query pattern that is a rounding error on Postgres can hold a lock long enough to wedge the entire store. There is no account to ban, because there is no account.

If you are on Postgres, MySQL, or MariaDB, this one does not apply. If you are on SQLite in production, patching closes this specific hole and leaves the foundation untouched — see below.

The stored XSS in the dashboard

An attacker persists a payload in a field that eventually renders in the admin UI — a product description, a customer note, something entity-shaped — and it executes in the browser session of whoever opens that page, which by definition is a privileged user. From there: session-token theft, forged Admin API requests with admin rights, or a quietly created second admin account.

Most stores have at least one customer-writable field that surfaces in the dashboard. Assume you are exposed unless you have actually traced every input path.

The file-upload type bypass

Uploads were accepted based on the Content-Type header the client sent, without verifying the bytes. A file claiming to be an image is stored as one. Whether that becomes something worse depends on where you write uploads and whether anything downstream will execute them — but "attacker chooses the file type" is a bad position regardless. If you have been running an affected version with public upload paths, check your asset storage for files whose contents do not match their extension.

The Shop API data exposure

The Shop API is the public, customer-facing GraphQL surface. List queries using filterOperator: OR could return non-public entities. Because that surface is public by design, there is no "only trusted users can reach it" mitigation. If you are on an affected version, you are affected. Patch regardless of your database or how locked down your admin is.

Why SQLite in production is still the through-line

Vendure ships SQLite support because it is genuinely convenient for local development and a fast way to stand up a proof of concept. The failure mode is predictable: the POC works, nobody swaps the database, and SQLite quietly becomes the production datastore.

The ReDoS advisory is the acute version of a chronic problem. Even without that particular bug, a SQLite-backed Vendure under real load degrades under write contention in ways that are hard to diagnose and impossible to fix without changing databases. If you are running Vendure on SQLite in production, the advisory is not the thing to fix — the database is.

What the 3.7 upgrade actually costs

3.7.0 is not a drop-in patch release. Budget for these before you schedule it:

  • The default superadmin password is refused in production. If your production environment still uses it, Vendure will not start. Change it before upgrading, or you will discover this during a deploy.
  • External authentication now requires a verified email to link to an existing account — that is the fix for the critical advisory. If you have a custom AuthenticationStrategy, it must set verified: true on returned user data for provider-verified emails, or linking is refused. Creating new accounts is unchanged.
  • Email plugin dependency majors: mjml 4 to 5 and nodemailer 6 to 9. Review both if you use MJML templates or a custom transport.
  • @nestjs/terminus is no longer a transitive dependency. If your own health-check code relied on it arriving via Vendure core, add it as a direct dependency.
  • Coupon codes are now compared case-insensitively. Only an issue if you used different-case versions of the same code for distinct promotions — those will now collide.

The upgrade and audit checklist

Patch, then verify. Patching without auditing leaves the door you already walked through open.

  • Go to 3.7.1, not the newest 3.6.x, if you use external authentication at all.
  • Upgrade @vendure/core and the dashboard packages together. Do not bump core alone and assume the dashboard fix came with it.
  • Change the superadmin password before the upgrade, not during.
  • If you have a custom AuthenticationStrategy, set verified: true for provider-verified emails, or external login breaks on deploy.
  • Force admin re-login after the XSS fix so any session that could already have been captured is invalidated.
  • Audit customer-writable fields that reach the admin UI and confirm output is escaped where it renders.
  • Check asset storage for files whose contents do not match their extension.
  • Review your own Shop API resolvers for the same over-fetch pattern; a framework fix does not cover code you wrote.
  • If you are on SQLite in production, plan the move to Postgres. Patching buys time; it does not fix the foundation.

What to do next

If you offer external login, treat this as a tonight upgrade to 3.7.1 and work through the breaking changes above. If you do not, and you are on the latest 3.6.x, you are covered for four of five and can schedule 3.7 properly.

And if "SQLite in production" gave you a flicker of recognition, that is the real signal. The version bump is a short job; getting off an embedded database and onto Postgres without dropping orders is the part worth doing carefully. That is the kind of migration we plan and run for legacy and existing ecommerce stacks — moving the data, not just the version number. If you want a second set of eyes on your Vendure deployment before you patch blind, get in touch.

Need this done on a real stack?

Magento 2, Adobe Commerce, migrations to Medusa.js or Vendure, enterprise Next.js, WordPress, and AI automation.

Contact us