Drupal Stores Are Under Attack. Nobody Will Say How.

CVE-2026-118539 in Drupal Commerce Core is exploited with no login needed. Here's how to find, patch and audit your clients' stores.

Drupal's security team has told online shops that someone is already exploiting a hole in the code that runs their checkout. It hasn't said how the attack works. What it has said is that shop owners should go through their own order history and look for anything that doesn't add up.

That is an unusual thing for an advisory to say. If you look after Drupal shops for clients, this is your week to find every one of them.

TL;DR

  • What happened: On 28 October 2026 Drupal published SA-CONTRIB-2026-254, a "Highly critical" (21/25) access bypass in Drupal Commerce Core, CVE-2026-118539. Drupal says it is actively exploited in the wild.
  • Am I exposed? Any client store running Commerce Core before 8.x-2.41, or 3.x before 3.3.13, is affected. No login is needed, and Drupal says every configuration is exploitable.
  • What to do: Preserve evidence, update the Commerce module itself (a Drupal core update alone does not fix it), then audit orders since September for totals that were never paid.
  • Impact: 42,002 sites report using the module on Drupal.org. How many were attacked, and by whom, is unconfirmed.

What is CVE-2026-118539 in Drupal Commerce Core?

CVE-2026-118539 is a missing-authorization flaw in Drupal Commerce Core, the module that gives Drupal sites a shopping cart, a checkout and commerce APIs for headless front ends. In Drupal's words, the module "doesn't sufficiently protect certain routes and entity fields". A route is a URL the site answers; an entity field is a stored value such as an order's state or total.

Think of a shop where the till is locked but a side door to the stockroom isn't. Nobody needs the till key if they can walk round the back.

Drupal's risk vector spells out how bad that is:

  • Access complexity: none. No special conditions are needed.
  • Authentication: none. Anonymous visitors can exploit it.
  • Confidentiality and integrity: some. Some non-public data can be read and some data can be changed.
  • Exploit: exists. Exploit code is already in use.
  • Target distribution: all. Every configuration of the module is exploitable.

The advisory adds that the bug "may financially impact the vendor". In plain terms, the store may lose money. Drupal has not published a CVSS score.

Is the Drupal Commerce vulnerability being exploited?

Yes. Drupal's advisory states that the vulnerability "is being actively exploited in the wild", and it shipped the fix and that warning together on 28 October 2026. The Hacker News notes that Drupal gave no details on the nature of the activity or the scope of the campaign. Who is behind it, how many shops were hit and whether a public proof of concept exists are all unconfirmed.

The flaw was reported by Dan Puccetti, Marcus Johansson and Robert Snyder, according to the advisory. The fixed releases are Commerce Core 3.3.13 and 8.x-2.41, both dated 28 October 2026.

No technical details means no log signature to grep for. Your detection tools are the version number and the order audit below.

How do I check and fix my clients' Drupal Commerce stores?

Work through these on every Drupal host you manage. Commands assume a Linux host, a MySQL or MariaDB database and Drush, run from the site's project root.

  1. Preserve evidence first. Dump the database and copy the web logs before you change anything, then hash the copies. Pass: the .sha256 file lists db.sql and the log files. (cp reports an error for whichever web server isn't installed; that is expected.)
D=/root/ir-commerce-$(date +%F); sudo mkdir -p "$D"
drush sql:dump | sudo tee "$D/db.sql" >/dev/null
sudo cp -a /var/log/apache2 /var/log/nginx "$D"/
sudo find "$D" -type f -exec sha256sum {} + | sudo tee "$D.sha256"
  1. Find every Commerce install on the host. Drupal 8 and later sites are normally built with Composer, so the installed version sits in each site's composer.lock. This searches local disks only, skipping network mounts. Pass: every "version" line shows 3.3.13 or later on the 3.x branch, or 2.41 or later on the 2.x branch (Composer may print it as 2.41.0 or 8.x-2.41).
sudo find / \( -fstype nfs -o -fstype nfs4 -o -fstype cifs -o -fstype proc \) -prune -o -name composer.lock -type f -print0 2>/dev/null | xargs -0 -r sudo grep -H -A1 '"name": "drupal/commerce"'
  1. Check running containers too. Sites in Docker keep their lock file inside the container, so step 2 can miss them. This loop runs the same search inside every running container; the pass is the same as step 2. Images that aren't running can't be checked this way: rebuild them from an updated composer.lock.
for c in $(docker ps -q); do docker exec "$c" sh -c 'find / -name composer.lock -not -path "/proc/*" 2>/dev/null | xargs -r grep -H -A1 "\"name\": \"drupal/commerce\""' | sed "s#^#$c: #"; done
  1. Update the Commerce module, not just core. Commerce Core is a contributed module, so updating Drupal core leaves this flaw in place. Use Drupal's Composer update steps. If composer.json pins an older version, run composer require drupal/commerce:^3.3.13 (or :^2.41 on the 2.x branch) instead of the update line.
composer update drupal/commerce --with-all-dependencies
drush updatedb -y
drush cache:rebuild
composer show drupal/commerce

Pass: the versions line from composer show reads 3.3.13 or later, or 2.41 or later on the 2.x branch.

  1. Audit orders for money that never arrived. Drupal tells sites to "audit their orders for inconsistencies". This Drush query lists orders placed since 1 September 2026 whose completed payments add up to less than the order total. Drupal hasn't said when exploitation began, so widen the date if the store patched late.
drush sql:query "SELECT o.order_id, o.state, o.total_price__number AS total, COALESCE(SUM(p.amount__number),0) AS paid, FROM_UNIXTIME(o.changed) AS changed FROM commerce_order o LEFT JOIN commerce_payment p ON p.order_id = o.order_id AND p.state = 'completed' WHERE o.placed >= UNIX_TIMESTAMP('2026-09-01') GROUP BY o.order_id HAVING paid < total ORDER BY o.changed DESC"

The column names follow Drupal's default storage for the Order entity. If the query errors, drush sql:query "DESCRIBE commerce_order" shows the real ones. Offline payment methods and refunds also land in this list, so each row is a lead, not proof. Pass: no rows, or every row matches a known offline payment or refund.

  1. Read the history of anything suspicious. If the store has the Commerce Log module enabled, each order's activity log appears on its View page at /admin/commerce/orders/<order id>. Pass: every state or price change on a flagged order traces back to a known staff member or the customer's own checkout.

Where KinoSec fits

A patch notice says a store might be exposed. Your client wants to know whether theirs is, and that means testing the live site.

KinoSec runs an autonomous pentest against your clients' web apps, external networks and Active Directory. On a Drupal shop it does the reconnaissance, finds the store and the routes it answers, and tests whether those routes give up or accept data they shouldn't without a login. That is exactly the class of bug CVE-2026-118539 belongs to, and the result is a findings report with remediation you can hand your client. Because it runs continuously, it also catches the next missing-authorization bug in a custom checkout tweak before an order audit does.

Frequently Asked Questions

What is CVE-2026-118539?

CVE-2026-118539 is a "Highly critical" (21/25) access bypass in Drupal Commerce Core, published on 28 October 2026 as SA-CONTRIB-2026-254. The module doesn't sufficiently protect certain routes and entity fields, so anonymous visitors can read some non-public data and change some data. Drupal says it is being actively exploited in the wild.

Which Drupal Commerce versions fix SA-CONTRIB-2026-254?

Commerce Core 3.3.13 fixes the 3.x branch and 8.x-2.41 fixes older sites. Updating Drupal core alone does not fix it, because Commerce Core is a contributed module. Run composer update drupal/commerce --with-all-dependencies and then drush updatedb -y.

How do I check if my clients' Drupal stores were hit?

Drupal has published no technical details, so there is no log pattern to search for. First, run composer show drupal/commerce in each site's root and confirm the version is 3.3.13 or later, or 2.41 or later on the 2.x branch. Then run the order audit query from step 5 above and investigate any order whose completed payments add up to less than its total. Finally, open each flagged order at /admin/commerce/orders/<order id> and read its activity log.

Can an autonomous pentest find this kind of bug?

An autonomous pentest like KinoSec's maps a client's web app and tests whether its routes and data can be read or changed without authorization, which is the class of flaw behind CVE-2026-118539. It turns "we think the store is patched" into a report your client can act on.