high · 7.5CVE-2026-63460Sep 17, 2026

CVE-2026-63460: Vendure Unauthenticated ReDoS via SQLite Regex Filter

Rohit Hatagale
AI Security Researcher, SecureLayer7

An unauthenticated attacker can send a single GraphQL request with a catastrophically backtracking regex to a Vendure shop running on SQLite, freezing the Node.js event loop and taking the entire…

Packagevendure/core
Ecosystemnpm
Affected<= 3.6.4
Fixed in3.6.5

The problem

Vendure registers a JavaScript user-defined function so SQLite can evaluate the REGEXP operator used by StringOperators.regex list filters. That UDF runs synchronously on the Node.js event loop via better-sqlite3 or sqljs.

The products query on the Shop GraphQL API carries no @Allow decorator, so it is publicly accessible with no credentials. Supplying a nested-quantifier pattern like (a+)+$ against a long string causes catastrophic backtracking, pegging the CPU for tens of seconds and making the storefront and admin panel completely unresponsive.

Repeated requests sustain the denial of service with minimal bandwidth.

Proof of concept

A working proof-of-concept for CVE-2026-63460 in vendure/core, with the exact payload below.

bash
curl -s -X POST http://localhost:3000/shop-api \
  -H "Content-Type: application/json" \
  -d '{"query":"{ products(options:{filter:{name:{regex:\"(a+)+$\"}}}) { items { id } } }"}'

The root cause (CWE-1333) is that list-query-builder.ts passes the raw StringOperators.regex value directly into new RegExp(pattern, 'i').test(value) inside the SQLite UDF, with no length cap, no safe-regex check, and no timeout. The pattern (a+)+$ is a classic nested-quantifier trap: matching it against 'a'.repeat(28) + 'b' takes roughly 20 seconds on a modern CPU, verified on Node.js v24.

The patch (commit f74cbbb) hardens input handling in the filter path. It either validates the pattern against a safe-regex library before constructing the RegExp, enforces a maximum pattern length, or both, so malicious patterns are rejected before they ever reach the UDF.

The fix

Upgrade @vendure/core to **3.6.5** (or 3.7.0+). Only deployments using the better-sqlite3 or sqljs database driver are affected; PostgreSQL and MySQL/MariaDB are not vulnerable because they delegate regex evaluation to the database engine, not the Node.js event loop.

As a defence-in-depth measure, consider adding @Allow(Permission.Authenticated) to ShopProductsResolver.products if anonymous product browsing is not required.

Reporter not attributed.

References: [1][2][3][4]

Related research