Automated Threat Modeling

Overview of CVE-2026-93389: LiteSpeed Cache Public REST Caching Exposes WooCommerce Shopper Data and Cart Tokens

A brief summary of CVE-2026-93389, an unauthenticated information disclosure in LiteSpeed Cache for WordPress through 7.9.1, where WooCommerce Store API cart and checkout responses were cached as public objects. The post covers the root cause, the 7.9.2 patch, and affected configurations.

CVE Analysis

8 min read

Gaurav Sarraf
Gaurav Sarraf

2026-11-04

Overview of CVE-2026-93389: LiteSpeed Cache Public REST Caching Exposes WooCommerce Shopper Data and Cart Tokens
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

On WooCommerce stores running LiteSpeed Cache with its default REST caching behavior, one shopper's cart or checkout data could be handed to the next anonymous visitor who requested the same Store API endpoint. That cached response carried names, addresses, email addresses, phone numbers, and the shopper's live Cart Token session JWT and nonce, which turns a privacy leak into a session hijacking problem.

LiteSpeed Cache is a WordPress plugin from LiteSpeed Technologies that provides page caching and site optimization, with its server-level caching features tied to OpenLiteSpeed, commercial LiteSpeed products, compatible hosting or QUIC.cloud. The official WordPress.org listing reports more than 7 million active installations and explicitly lists WooCommerce compatibility. Because the plugin sits in front of so many WordPress sites, a cache isolation mistake has a wide potential footprint, although only stores using the WooCommerce Store API with REST caching enabled are in scope here.

Wordfence, acting as CNA, scores CVE-2026-93389 at CVSS 3.1 8.2 (High) and classifies it as CWE-200. All versions up to and including 7.9.1 are affected, and the fix ships in 7.9.2.

Technical information

Scoring

The vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N: network reachable, low complexity, no privileges, no user interaction, high confidentiality impact and low integrity impact. NVD has not supplied its own assessment. The score comes from Wordfence.

Root cause: every REST request becomes cacheable

With the Cache REST API option enabled (it ships ON by default), Control::init_cacheable() marks every REST request as cacheable as soon as the REST API initializes:

// Hook WP REST to be cacheable. if ( $this->conf( Base::O_CACHE_REST ) ) { add_action( 'rest_api_init', [ $this, 'set_cacheable' ], 5 ); }

The WooCommerce Store API uses the same REST plumbing as any other WordPress route. Its /wc/store/v1/cart and /wc/store/v1/checkout GET responses, however, are specific to one shopper's session. Before 7.9.2, nothing excluded those routes, and the cache did not vary on the Cart Token or the WooCommerce session. The first personalized response for a given URL could therefore be stored as a public cache object and served to anyone who asked next.

The existing safeguards did not help. LiteSpeed's documentation states that the ordinary Cart, Checkout and My Account pages are excluded from caching by default. Those page exclusions do not apply to the separate Store API REST responses, so a store with a sensible-looking page cache configuration could still be exposing cart and checkout data through the REST path.

What leaks

The Wordfence advisory identifies four categories of data in the cached responses:

  • Billing and shipping identity: name, company, street address, email and phone
  • Shopping activity: cart contents and totals
  • Session credentials: the shopper's live Cart Token JWT and nonce
  • Checkout identifier: order_key on the checkout endpoint

Why the Cart Token matters

WooCommerce documentation explains that Cart Tokens can replace cookie-based sessions, identify the associated cart, and support checkout requests, and that a nonce is not required when a Cart Token is used. The Store API normally requires a nonce or Cart Token for checkout endpoints. A leaked token is therefore usable session material, which is what lets this issue move from data exposure into cart and checkout session hijacking.

WooCommerce's GET checkout operation returns checkout data, including a draft order and billing and shipping addresses, while the POST operation handles final checkout and attempts payment. The CVE concerns the exposure of cached GET responses and the session material inside them; the sources do not show that reading a cached response automatically completes a purchase.

Attack flow

Based on the advisory description, exploitation is cached response reuse rather than credential guessing:

  1. A legitimate shopper's browser requests /wc/store/v1/cart or /wc/store/v1/checkout. The origin returns a personalized response.
  2. Because REST caching marked the request cacheable and no vary on the Cart Token or session existed, LiteSpeed stores that response as a public cache object.
  3. An unauthenticated client sends a request for the same endpoint with no cookies and no token.
  4. LiteSpeed answers from cache as an LSCache HIT, returning the first shopper's billing and shipping details, cart contents and totals, Cart Token JWT and nonce, and, on the checkout endpoint, the order_key.
  5. The attacker can present the leaked Cart Token to the Store API to interact with the victim's cart or checkout session.

The necessary conditions are an affected plugin version, REST caching enabled, active use of the Store API cart or checkout endpoints, and a personalized response currently present in the cache. Not every request will expose a customer, and not every LiteSpeed installation meets these conditions.

Patch information

LiteSpeed fixed CVE-2026-93389 in LiteSpeed Cache for WordPress 7.9.2. According to the vendor's timeline, Wordfence reported the issue on September 17, 2026, and 7.9.2 went to the WordPress.org repository on October 19, 2026. Wordfence lists 7.9.2 as the patched version and every release up to and including 7.9.1 as affected.

Fix part 1: refuse to cache Store API routes

Upstream GitHub commit b587d2b, titled "Bypassed page cache for WooCommerce Store API requests", adds a REST filter to the WooCommerce integration in thirdparty/woocommerce.cls.php:

+use LiteSpeed\Control; ... add_action('litespeed_tag_finalize', [ $this, 'set_tag' ]); + add_filter( 'rest_pre_dispatch', [ $this, 'nocache_store_api' ], 1, 3 ); ... + public function nocache_store_api( $result, $server, $request ) { + $route = is_object( $request ) && is_callable( [ $request, 'get_route' ] ) ? $request->get_route() : ''; + if ( is_string( $route ) && ( '/wc/store/' === substr( $route, 0, 10 ) || '/wc/store' === $route ) ) { + Control::set_nocache_hard( 'WooCommerce Store API' ); + } + return $result; + }

A few design choices stand out:

  • rest_pre_dispatch at priority 1. This filter runs for every REST request after routing and before the endpoint handler, so the no-cache decision is made before any cart data is produced. The callback returns $result unchanged. It never takes over the request and only flips the cache control state.
  • Matching on the resolved route, not the raw URL. get_route() returns the normalized REST route whether the request arrived as /wp-json/wc/store/... or ?rest_route=/wc/store/..., which closes simple URL-shape bypasses. The /wc/store/ prefix check covers v1, any future Store API versions, and the bare namespace.
  • Excluding instead of varying. The patch does not attempt to vary the cache on the Cart Token. It removes these per-session endpoints from the cache entirely, which is the safe choice for data that is never shareable.

Fix part 2: a hard no-cache that settings cannot override

A plain set_nocache() was not sufficient, because LSCWP lets administrators force caching via Force Public Cache URIs and Force Cache URIs, and is_cacheable() honored those first. In 7.9.2, src/control.cls.php adds a new bitmask flag and a stronger setter, both marked @since 7.9.2:

const BM_NOCACHE_HARD = 512; ... public static function set_nocache_hard( $reason = false ) { self::$_control |= self::BM_NOTCACHEABLE | self::BM_NOCACHE_HARD; self::debug( 'X Cache_control -> no Cache (hard) ' . ( is_string( $reason ) ? "( $reason )" : '' ), 5 ); }

is_cacheable() now checks this bit ahead of the forced public and forced cacheable shortcuts:

if ( self::$_control & self::BM_NOCACHE_HARD ) { return false; } // If it's forced public cacheable. if ( self::is_public_forced() ) { return true; }

Even if an administrator added a broad rule such as /wp-json/* to the force public list, a Store API response is still emitted with a no-cache directive in the LiteSpeed cache control header, because output() emits no-cache whenever is_cacheable() is false. The 7.9.2 finalize() also applies the same hard flag to authenticated REST requests (logged-in users, or requests carrying PHP_AUTH_USER or Authorization headers, such as Application Passwords), as part of a wider identity isolation hardening in this release. The official changelog for the release likewise describes hardening of visitor isolation, vary cookies, Guest Mode, cache control permissions and Force Public safeguards.

Source notes

The NVD and Wordfence records point to WordPress.org SVN changeset 3757253 (trunk/src/control.cls.php), labeled Release v7.9.2, as the fix reference. That page would not load during verification, so the control.cls.php code above comes from the v7.9.2 tag on GitHub rather than the SVN diff itself.

Commit b587d2b also bundles two unrelated fixes: a manage_options capability check before WCML crawler options are saved (thirdparty/wcml.cls.php), and deduplication of product purges in the Advanced Bulk Edit handler. Neither changes the fix for this CVE.

Interim containment and limits

Where an update cannot be applied immediately, VulDB recommends disabling REST caching for WooCommerce endpoints through plugin settings or server configuration. It also mentions reverse-proxy cache variation on Cookie and Authorization as additional isolation guidance. That is secondary guidance, not a demonstrated substitute for the patch.

The reviewed advisories do not provide a procedure for invalidating previously exposed Cart Tokens, identifying affected shoppers, or proving that historical cached copies were removed. Applying 7.9.2 stops new exposure, but it should not be read as evidence that earlier disclosure has been reversed.

Affected systems and versions

  • Product: LiteSpeed Cache plugin for WordPress (vendor litespeedtech)
  • Affected versions: all versions up to and including 7.9.1
  • Fixed version: 7.9.2 or newer
  • Vulnerable configuration: Cache REST API enabled, which is the shipped default, on a site exposing the WooCommerce Store API endpoints /wc/store/v1/cart and /wc/store/v1/checkout
  • Not a mitigating factor: LiteSpeed's default exclusions for the Cart, Checkout and My Account pages do not cover the Store API REST responses

The 7+ million installation figure describes overall plugin adoption, not the number of vulnerable WooCommerce stores.

On exploitation status, the reviewed records do not confirm active exploitation, name a threat actor or campaign, or establish a public proof of concept. VulDB lists KEV status as no and activity as very low. Wordfence published on November 4, 2026 and NVD on November 5, 2026. These are disclosure dates, not an attack timeline.

Vendor security history

The most relevant prior case is CVE-2024-28000, an unauthenticated privilege escalation in LiteSpeed Cache reported by Patchstack. LiteSpeed explained that the Crawler feature's Role Simulation functionality used a weak security hash, and that an additional weakness allowed the hash to be generated and saved even when the crawler was not enabled. Exposure extended to sites where an attacker could guess an administrator-level user ID.

LiteSpeed's published response recorded notification on August 5, 2024, release of the 6.4 patch on August 13, and inclusion in control panel stable releases on August 20, along with advice to check for unrecognized administrator accounts. That issue concerned role simulation and privileges, whereas CVE-2026-93389 concerns public caching of shopper-specific REST data. In both cases the vendor published fixes and response information. For the current issue, the vendor documents the timeline from the September 17, 2026 report to the October 19, 2026 release.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization