Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘 Packagist

GHSA-875v-7m49-8x88

GHSA-875v-7m49-8x88 is a remote code execution vulnerability in craftcms/commerce. O3 Security confirms whether GHSA-875v-7m49-8x88 is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Craft Commerce has a SQL Injection can lead to Remote Code Execution via TotalRevenue Widget

Also known asCVE-2026-32271
Published
Apr 14, 2026
Updated
Apr 14, 2026
Affected
2 pkgs
Patched
2 / 2
Exploits
None indexed

Blast Radius

2 pkgs affected
🐘craftcms/commerce🐘craftcms/commerce

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Summary

A SQL injection in the Commerce TotalRevenue widget can lead to remote code execution through a chain of four vulnerabilities:

  • SQL Injection -- The TotalRevenue stat interpolates unsanitized widget settings directly into a sprintf-based SQL Expression. Any control panel user can create any widget type without permission checks.

  • PDO Multi-Statement Queries -- PHP PDO MySQL enables CLIENT_MULTI_STATEMENTS by default. Neither Yii2 nor Craft CMS disables it. This allows stacking an INSERT statement after the injected SELECT , writing a maliciously serialized PHP object into the queue table.

  • Unrestricted unserialize() -- The yii2-queue PhpSerializer calls unserialize() with no allowed_classes restriction on every queue job. When the queue consumer processes the injected job, it instantiates the attacker-controlled object.

  • Gadget Chain (FileCookieJar) -- GuzzleHttp\Cookie\FileCookieJar (a standard Guzzle dependency) has an unguarded __destruct() method that calls file_put_contents(). The attacker’s serialized payload writes a PHP webshell to the server’s webroot. PHP tags survive json_encode() because Guzzle uses options=0 (no JSON_HEX_TAG).

The complete chain requires 3 HTTP requests and achieves arbitrary command execution as the PHP process user. Queue processing is triggered via GET /actions/queue/run, an endpoint that requires no authentication ($allowAnonymous = ['run']).

RCE Exploitation Steps

  • Authenticate as any control panel user
  • POST to /admin/actions/dashboard/create-widget with stacked SQL injection:
  • settings[type] contains the stacked INSERT with the serialized gadget chain
  • Response: HTTP 500 (expected -- INSERT already committed)
  • Trigger queue processing: GET /actions/queue/run
  • Queue consumer deserializes the gadget chain
  • FileCookieJar::__destruct() writes webshell to webroot
  • Access the webshell: GET /poc_rce.php?c=id
  • Response: uid=1000(home) gid=1000(home) groups=1000(home)

Affected Packages

2 total 2 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistcraftcms/commerce4.0.0&&< 4.10.34.10.3
🐘Packagistcraftcms/commerce5.0.0&&< 5.5.55.5.5

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for craftcms/commerce. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update craftcms/commerce to 4.10.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-875v-7m49-8x88 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-875v-7m49-8x88 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-875v-7m49-8x88. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## Summary A SQL injection in the Commerce TotalRevenue widget can lead to remote code execution through a chain of four vulnerabilities: * SQL Injection -- The TotalRevenue stat interpolates unsanitized widget settings directly into a sprintf-based SQL Expression. Any control panel user can create any widget type without permission checks. * PDO Multi-Statement Queries -- PHP `PDO MySQL` enables `CLIENT_MULTI_STATEMENTS` by default. Neither Yii2 nor Craft CMS disables it. This allows stacking an INSERT statement after the injected SELECT , writing a maliciously serialized PHP object into
O3 Security · Impact-Aware SCA

Is GHSA-875v-7m49-8x88 in your dependencies?

O3 detects GHSA-875v-7m49-8x88 across Packagist dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.