CVE-2024-58136: Yii Framework 2 Behavior Attachment Vulnerability
Executive Summary
CVE-2024-58136 is a critical vulnerability affecting the Yii Framework 2, specifically versions prior to 2.0.52. This vulnerability stems from improper handling of behavior attachment when the behavior is defined using the __class
array key. It's a regression of CVE-2024-4990 and was actively exploited in the wild between February and April 2025. Successful exploitation can lead to unauthorized access and control over the affected system. The vulnerability has a CVSS v3.1 base score of 9.0, indicating its critical severity.
Technical Details
The vulnerability resides in the Component.php
file within the Yii Framework 2. It affects how behaviors are attached to components. Behaviors are a powerful feature in Yii that allows developers to add functionality to existing classes without modifying them directly. The vulnerability specifically arises when a behavior is defined as an array with the __class
key specifying the behavior's class name.
Affected Systems:
- Yii Framework 2 versions prior to 2.0.52
Affected Component:
framework/base/Component.php
Vulnerable Code Snippet (Prior to Patch):
public function __set($name, $value)
{
if (strncmp($name, 'on ', 3) === 0) {
// attaching an event handler
$name = trim(substr($name, 3));
$this->on($name, $value);
} elseif (strncmp($name, 'as ', 3) === 0) {
// attaching a behavior
$name = trim(substr($name, 3));
if ($value instanceof Behavior) {
$this->attachBehavior($name, $value);
} elseif (isset($value['class']) && is_subclass_of($value['class'], Behavior::class, true)) {
$this->attachBehavior($name, Yii::createObject($value));
} elseif (is_string($value) && is_subclass_of($value, Behavior::class, true)) {
$this->attachBehavior($name, Yii::createObject($value));
} else {
throw new InvalidConfigException('Invalid behavior configuration');
}
} else {
// setting a property
try {
parent::__set($name, $value);
} catch (UnknownPropertyException $e) {
if (method_exists('__set', 'set' . $name)) {
$this->{'set' . $name}($value);
} else {
throw $e;
}
}
}
}
The code above shows the __set
magic method in the Component
class. This method is invoked when writing data to inaccessible properties. The relevant part for this vulnerability is the section that handles behavior attachment (lines starting with elseif (strncmp($name, 'as ', 3) === 0)
). Before the patch, the code only checked for the class
key in the $value
array to determine if a behavior should be attached using Yii::createObject()
. The check for the __class
key was missing, leading to the vulnerability.
Root Cause Analysis
The root cause of CVE-2024-58136 is the incomplete handling of behavior configurations within the __set
method of the Component
class. Specifically, the code failed to recognize and process behavior definitions that used the __class
key instead of the class
key. This oversight allowed attackers to bypass intended security checks and potentially inject malicious behaviors into the application.
The vulnerability is a regression of CVE-2024-4990, indicating that a previous fix or change inadvertently reintroduced the issue. This highlights the importance of thorough regression testing when applying security patches.
The Yii::createObject()
method is used to instantiate objects based on configuration arrays. When the __class
key is used, it specifies the class to be instantiated. If this key is not properly handled, an attacker could potentially specify an arbitrary class, leading to code execution vulnerabilities.
Illustrative Example:
Consider the following code snippet that attempts to attach a behavior:
$component->{'as malicious'} = ['__class' => 'MaliciousBehavior'];
If MaliciousBehavior
is a class that performs malicious actions, such as reading sensitive files or executing arbitrary code, an attacker could exploit this vulnerability to compromise the system.
Patch Analysis
The fix for CVE-2024-58136 involves modifying the __set
method in framework/base/Component.php
to correctly handle behavior definitions using the __class
key.
Diff Code Block:
--- a/framework/base/Component.php
+++ b/framework/base/Component.php
@@ -190,7 +190,7 @@ public function __set($name, $value)
$name = trim(substr($name, 3));
if ($value instanceof Behavior) {
$this->attachBehavior($name, $value);
- } elseif (isset($value['class']) && is_subclass_of($value['class'], Behavior::class, true)) {
+ } elseif ((isset($value['class']) && is_subclass_of($value['class'], Behavior::class)) || (isset($value['__class']) && is_subclass_of($value['__class'], Behavior::class))) {
$this->attachBehavior($name, Yii::createObject($value));
} elseif (is_string($value) && is_subclass_of($value, Behavior::class, true)) {
$this->attachBehavior($name, Yii::createObject($value));
Explanation:
The patch modifies the elseif
condition to check for both class
and __class
keys. The is_subclass_of
function is used to ensure that the specified class is a subclass of Behavior
. The true
parameter in the original code is_subclass_of($value['class'], Behavior::class, true)
enforces autoloading, which was removed in the patched version. The patched version checks if either the class
key exists and its value is a subclass of Behavior
, or if the __class
key exists and its value is a subclass of Behavior
. This ensures that behaviors defined using either key are correctly attached.
Additional Changes:
The patch also includes changes to the CHANGELOG.md
file to document the fix and a new test case in tests/framework/base/ComponentTest.php
to verify the fix.
CHANGELOG.md:
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -4,8 +4,7 @@ Yii Framework 2 Change Log
2.0.52 under development
------------------------
-- no changes in this release.
-
+- Bug #20232: Fix regression introduced in `GHSA-cjcc-p67m-7qxm` while attaching behavior defined by `__class` array key (erickskrauch)
2.0.51 July 18, 2024
--------------------
This entry in the changelog clearly indicates that the fix addresses the regression introduced by GHSA-cjcc-p67m-7qxm and specifically targets the issue with attaching behaviors defined using the __class
array key.
ComponentTest.php:
--- a/tests/framework/base/ComponentTest.php
+++ b/tests/framework/base/ComponentTest.php
@@ -341,6 +341,9 @@ public function testAttachBehavior()
$this->assertTrue($component->hasProperty('p'));
$component->test();
$this->assertTrue($component->behaviorCalled);
+
+ $component->{'as c'} = ['__class' => NewBehavior::class];
+ $this->assertNotNull($component->getBehavior('c'));
}
public function testAttachBehaviors()
This test case adds a new behavior using the __class
key and asserts that the behavior is successfully attached to the component. This ensures that the fix is working as expected and prevents future regressions.
Exploitation Techniques
An attacker can exploit CVE-2024-58136 by crafting a malicious request that includes a behavior definition with the __class
key pointing to a malicious class. This class could then be instantiated and executed within the context of the application, allowing the attacker to perform arbitrary actions.
Attack Scenario:
- The attacker identifies a Yii Framework 2 application running a vulnerable version (prior to 2.0.52).
- The attacker finds a component that allows attaching behaviors via user-controlled input (e.g., through a form submission or API endpoint).
- The attacker crafts a request that includes a behavior definition with the
__class
key pointing to a malicious class. - The application processes the request and attempts to attach the behavior.
- Due to the vulnerability, the malicious class is instantiated and executed.
- The attacker gains unauthorized access to the system or performs other malicious actions.
Proof-of-Concept (PoC) - Made-up:
Let's assume we have a MaliciousBehavior
class that executes a system command:
<?php
namespace app\components;
use yii\base\Behavior;
class MaliciousBehavior extends Behavior
{
public function attach($owner)
{
parent::attach($owner);
// WARNING: This is a dangerous operation and should only be used for demonstration purposes!
system('echo "Exploited!" > /tmp/exploited.txt');
}
}
An attacker could then send the following request to attach this behavior:
$component->{'as exploit'} = ['__class' => 'app\components\MaliciousBehavior'];
This would result in the MaliciousBehavior
class being instantiated and the system()
command being executed, creating a file named /tmp/exploited.txt
with the content "Exploited!".
Real-World Impact:
The real-world impact of CVE-2024-58136 could be significant. An attacker could use this vulnerability to:
- Gain unauthorized access to sensitive data.
- Modify application data.
- Execute arbitrary code on the server.
- Compromise the entire system.
- Launch further attacks against other systems on the network.
Mitigation Strategies
To mitigate CVE-2024-58136, the following strategies are recommended:
- Upgrade to Yii Framework 2.0.52 or later: This is the most effective way to address the vulnerability. The updated version includes the necessary patch to correctly handle behavior attachments.
- Input Validation: Implement strict input validation to prevent attackers from injecting malicious behavior definitions. Sanitize and validate all user-controlled input that is used to configure components and behaviors.
- Web Application Firewall (WAF): Deploy a WAF to detect and block malicious requests that attempt to exploit this vulnerability. Configure the WAF to filter out requests that contain suspicious behavior definitions.
- Principle of Least Privilege: Ensure that the application runs with the minimum necessary privileges. This can limit the impact of a successful exploit.
- Regular Security Audits: Conduct regular security audits to identify and address potential vulnerabilities in the application.
- Monitor for Suspicious Activity: Implement monitoring and logging to detect suspicious activity that may indicate an attempted exploit.
Configuration Changes:
While upgrading is the primary solution, consider these configuration adjustments for defense in depth:
- Disable Dynamic Behavior Attachment (If Possible): If your application doesn't require dynamic behavior attachment via user input, consider disabling this feature altogether. This can significantly reduce the attack surface.
- Restrict Behavior Classes: If dynamic behavior attachment is necessary, restrict the allowed behavior classes to a predefined whitelist. This can prevent attackers from injecting arbitrary classes.
Timeline of Discovery and Disclosure
- Vulnerability Discovered: Unknown
- Vulnerability Reported: Unknown
- Patch Released: July 24, 2024 (Commit Hash: 40fe496eda529fd1d933b56a1022ec32d3cd0b12)
- CVE Assigned: CVE-2024-58136
- Public Disclosure: April 10, 2025