DEV Community

CVE Reports
CVE Reports

Posted on • Originally published at cvereports.com

GHSA-265M-7826-WJQM: GHSA-265m-7826-wjqm: Authenticated Remote Code Execution in Craft CMS via condition.config JSON Cleanse Bypass

GHSA-265m-7826-wjqm: Authenticated Remote Code Execution in Craft CMS via condition.config JSON Cleanse Bypass

Vulnerability ID: GHSA-265M-7826-WJQM
CVSS Score: 8.7
Published: 2026-08-06

Craft CMS contains an authenticated remote code execution vulnerability due to a sanitization bypass in its search condition configuration parser. An attacker with access to the control panel can inject unsafe Yii2 behavior configurations wrapped inside a JSON-encoded string. When decoded and merged by the application, these keys bypass the global config cleanse filter and are evaluated by the Yii2 component factory, leading to arbitrary code execution.

TL;DR

An authenticated remote code execution vulnerability exists in Craft CMS versions 4.x and 5.x. The flaw allows an attacker to bypass global configuration sanitization by nesting Yii2 behavior injection keys inside a JSON-encoded search condition property, resulting in command execution when the object is instantiated.


⚠️ Exploit Status: POC

Technical Details

  • Vulnerability Type: Improper Control of Generation of Code ('Code Injection') (CWE-94) / Deserialization of Untrusted Data (CWE-502)
  • Attack Vector: Network (Authenticated session required with access to search filters)
  • CVSS Score: 8.7 (High)
  • Exploit Status: None / Proof-of-Concept
  • KEV Status: Not Listed

Affected Systems

  • Craft CMS
  • Craft CMS: >= 5.0.0-RC1, < 5.10.6 (Fixed in: 5.10.6)
  • Craft CMS: >= 4.0.0-RC1, < 4.18.2 (Fixed in: 4.18.2)

Code Analysis

Commit: 353b5d6

Fix a high-severity RCE vulnerability in Craft CMS 5.x conditions

diff --git a/src/services/Conditions.php b/src/services/Conditions.php
index 5786fb6f87e..3f6ed789b5c 100644
--- a/src/services/Conditions.php
+++ b/src/services/Conditions.php
@@ -11,6 +11,7 @@
 use craft\base\conditions\ConditionInterface;
 use craft\base\conditions\ConditionRuleInterface;
 use craft\helpers\ArrayHelper;
+use craft\helpers\Component as ComponentHelper;
 use craft\helpers\Json;
 use ReflectionException;
 use ReflectionProperty;
@@ -54,7 +55,7 @@ public function createCondition(array|string $config): ConditionInterface
         // The base config will be JSON-encoded within a `config` key if this came from a condition builder
         if (isset($config['config']) && Json::isJsonObject($config['config'])) {
             $config = array_merge(
-                Json::decode(ArrayHelper::remove($config, 'config')),
+                ComponentHelper::cleanseConfig(Json::decode(ArrayHelper::remove($config, 'config'))),
                 $config
             );
         }
@@ -93,6 +94,7 @@ public function createConditionRule(array|string $config): ConditionRuleInterfac
                     $newClass = $newConfig;
                     $newConfig = [];
                 } else {
+                    $newConfig = ComponentHelper::cleanseConfig($newConfig);
                     $newClass = ArrayHelper::remove($newConfig, 'class');
                 }
Enter fullscreen mode Exit fullscreen mode

Commit: 789789d

Backport high-severity RCE vulnerability fix to Craft CMS 4.x

diff --git a/src/services/Conditions.php b/src/services/Conditions.php
index 5786fb6f87e..3f6ed789b5c 100644
--- a/src/services/Conditions.php
+++ b/src/services/Conditions.php
@@ -11,6 +11,7 @@
 use craft\base\conditions\ConditionInterface;
 use craft\base\conditions\ConditionRuleInterface;
 use craft\helpers\ArrayHelper;
+use craft\helpers\Component as ComponentHelper;
 use craft\helpers\Json;
 use ReflectionException;
 use ReflectionProperty;
@@ -54,7 +55,7 @@ public function createCondition(array|string $config): ConditionInterface
         // The base config will be JSON-encoded within a `config` key if this came from a condition builder
         if (isset($config['config']) && Json::isJsonObject($config['config'])) {
             $config = array_merge(
-                Json::decode(ArrayHelper::remove($config, 'config')),
+                ComponentHelper::cleanseConfig(Json::decode(ArrayHelper::remove($config, 'config'))),
                 $config
             );
         }
@@ -93,6 +94,7 @@ public function createConditionRule(array|string $config): ConditionRuleInterfac
                     $newClass = $newConfig;
                     $newConfig = [];
                 } else {
+                    $newConfig = ComponentHelper::cleanseConfig($newConfig);
                     $newClass = ArrayHelper::remove($newConfig, 'class');
                 }
Enter fullscreen mode Exit fullscreen mode

Mitigation Strategies

  • Upgrade to patched versions of Craft CMS immediately.
  • Restrict administrative and control panel access to trusted IP addresses.
  • Deploy WAF rules to detect and block nested JSON keys containing behavior modifiers.

Remediation Steps:

  1. Verify the current running version of Craft CMS inside composer.json.
  2. Execute the command composer update craftcms/cms to fetch security updates.
  3. Ensure the version resolved is 4.18.2 or greater (for Craft CMS 4) or 5.10.6 or greater (for Craft CMS 5).
  4. Deploy the updated codebase to staging and production environments.
  5. Restart PHP-FPM or Apache services to clear any opcode cache.

References


Read the full report for GHSA-265M-7826-WJQM on our website for more details including interactive diagrams and full exploit analysis.

Top comments (0)