CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2024-58136

The Doppelgänger Class: How a Failed Fix in Yii 2 Led to Mass RCE

Alon Barad
Alon Barad
Software Engineer

Feb 26, 2026·5 min read·160 visits

Executive Summary (TL;DR)

A critical RCE in Yii 2 (< 2.0.52) caused by a regression in a previous security fix. Attackers bypass class validation by using the `__class` key instead of `class`, allowing arbitrary object instantiation and code execution. Actively exploited.

History has a funny way of repeating itself, especially in PHP frameworks. CVE-2024-58136 is not just a vulnerability; it is a masterclass in how 'patching' can sometimes just mean 'moving the target.' In July 2024, the Yii team patched a critical RCE (CVE-2024-4990) involving behavior attachments. They added a check. It looked solid. But they forgot one tiny detail about their own Dependency Injection container: it speaks two languages. By simply using `__class` instead of `class`, attackers could bypass the check entirely, leading to active exploitation in the wild, particularly devastating for Craft CMS installations.

The Hook: A Tale of Two Patches

In the world of secure coding, the most dangerous moment is often immediately after a patch is released. Why? Because developers relax, and hackers start diffing. In July 2024, Yii Framework released version 2.0.51 to fix a nasty Remote Code Execution bug (CVE-2024-4990). The issue was simple: you could attach 'behaviors' (mixins) to components via user input, and if you attached a malicious class, you got RCE.

The fix seemed logical: before attaching a behavior, check if the requested class is actually a subclass of yii\base\Behavior. It’s like checking ID at the door of a club. If you aren't on the list, you don't get in.

But here is where the plot twists. The Yii Dependency Injection (DI) container is a polyglot. It accepts definitions in multiple formats. The developers checked one format (class), but the DI container happily prioritizes another (__class). It’s like the bouncer checking your ID, but the bartender serving anyone who whispers a secret password. This oversight turned a 'security fix' into a blueprint for bypass.

The Flaw: Logic vs. Reality

To understand this vulnerability, you have to understand how Yii creates objects. The Yii::createObject($config) method is the heart of the framework. It takes a configuration array and spits out an object. Usually, you specify the type of object using the class key.

However, for historical reasons or advanced configuration merging, Yii also supports __class. When Yii::createObject receives an array, it looks for __class first. If found, it uses that class name. If not, it falls back to class.

The vulnerability lies in yii\base\Component::__set. This magic method handles property assignment. When you try to assign a configuration to a property like as myBehavior, Yii attempts to attach it. In version 2.0.51, the code validated config['class']. It ensured config['class'] was a safe Behavior subclass.

But then it passed the entire config array to Yii::createObject.

So, if an attacker sends a payload with both keys:

  1. class: "SafeBehavior" (The bouncer checks this. It's safe. Pass.)
  2. __class: "MaliciousGadget" (The factory uses this. It's deadly. Boom.)

The validation logic and the execution logic were looking at different parts of the same data structure. This is a classic "Time-of-Check to Time-of-Use" (TOCTOU) style logic error, but purely with array keys.

The Code: The Smoking Gun

Let's look at the diff. It is painfully simple, which makes it all the more tragic.

Here is the vulnerable code in 2.0.51:

// yii/base/Component.php
} elseif (isset($value['class']) && is_subclass_of($value['class'], Behavior::class, true)) {
    // The check passes if 'class' is valid.
    // But createObject might use '__class' if it exists in $value!
    $this->attachBehavior($name, Yii::createObject($value));
}

And here is the fix in 2.0.52:

// yii/base/Component.php
} elseif (
    (isset($value['class']) && is_subclass_of($value['class'], Behavior::class)) ||
    // NOW we check __class too
    (isset($value['__class']) && is_subclass_of($value['__class'], Behavior::class))
) {
    $this->attachBehavior($name, Yii::createObject($value));
}

The fix is literally just acknowledging the existence of the shadow key. If you are a developer, write this on a sticky note: "Validate the data you use, not the data you expect."

The Exploit: Weaponizing the Shadow Key

So how do we turn this into a shell? We need a target application that allows user input to flow into a component configuration. Craft CMS was the unlucky winner here, exposing this via image transform settings.

The attack requires a "Gadget"—a PHP class that does something dangerous when instantiated or destructed. A classic favorite in the PHP ecosystem is GuzzleHttp\Psr7\FnStream. This class has a destructor that calls a user-defined function.

Here is what a weaponized JSON payload looks like:

{
  "as trigger": {
    "class": "yii\\behaviors\\AttributeBehavior", 
    "__class": "GuzzleHttp\\Psr7\\FnStream",
    "__construct()": [[]],
    "_fn_close": "system",
    "methods": {
        "close": "id"
    }
  }
}

The Breakdown:

  1. as trigger: Tells Yii to attach a behavior named "trigger".
  2. class: Points to AttributeBehavior. This satisfies the security check in 2.0.51.
  3. __class: Points to FnStream. This is what Yii::createObject actually builds.
  4. _fn_close: The property on FnStream that holds the function name to call on destruction (system).
  5. close: The argument passed to the function.

When the request ends, the FnStream object is destroyed, system('id') is executed, and the attacker wins.

The Impact: From CMS to C2

This isn't theoretical. This is in the CISA Known Exploited Vulnerabilities (KEV) catalog. Attackers are actively scanning the internet for unpatched Yii applications, specifically Craft CMS.

Once RCE is achieved, the game is over. In the wild, we've seen attackers using this to:

  1. Drop Web Shells: Persistent access via standard PHP shells.
  2. Exfiltrate Configs: Stealing db.php or .env files to get database credentials.
  3. Lateral Movement: Using the compromised server to attack internal networks or send spam.

Because this runs as the web server user (usually www-data), the attacker has full read/write access to the webroot. In modern containerized environments, they might just steal environment variables and move on. In legacy VPS hosting, they own the box.

The Fix: Stop the Bleeding

If you are running Yii 2, check your composer.json immediately. If your version is < 2.0.52, you are vulnerable.

Remediation Steps:

  1. Update: Run composer update yiisoft/yii2. Ensure you land on at least 2.0.52.
  2. Craft CMS: Update to the latest version immediately (e.g., Craft 4.10.2+ or 5.2.3+).
  3. Verify: Check your vendor/yiisoft/yii2/base/Component.php file manually if you cannot update immediately. Look for the __class check in __set.

If you cannot patch (why?), you can try to mitigate this at the WAF level by blocking requests containing __class in the body, but this is risky and prone to false positives or bypasses (e.g., JSON encoding variations). Patching is the only real fix.

Official Patches

YiiSoftOfficial advisory urging upgrade to 2.0.52

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
67.06%
Top 1% most exploited

Affected Systems

Yii Framework < 2.0.52Craft CMS (versions utilizing vulnerable Yii)Any PHP application utilizing Yii 2 component configuration via user input

Affected Versions Detail

Product
Affected Versions
Fixed Version
Yii Framework
YiiSoft
< 2.0.522.0.52
Craft CMS
Pixel & Tonic
Various (depends on Yii version)Latest Stable
AttributeDetail
CWE IDCWE-502 (Deserialization of Untrusted Data)
CVSS v3.19.8 (Critical)
Attack VectorNetwork (Remote)
ImpactRemote Code Execution (RCE)
Exploit StatusActive / Weaponized
KEV StatusListed (2025-05-02)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.003Command and Scripting Interpreter: Windows Command Shell
Execution
T1203Exploitation for Client Execution
Execution
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Known Exploits & Detection

SensePostAnalysis of in-the-wild campaign targeting Craft CMS using this Yii gadget chain.
GitHubCommit demonstrating the regression fix.
NucleiDetection Template Available

Vulnerability Timeline

Yii 2.0.51 released (Fixes CVE-2024-4990, introduces regression)
2024-07-18
Regression identified and fixed in code (Commit 40fe496)
2024-07-24
Active in-the-wild exploitation detected (Craft CMS campaigns)
2025-02-10
Added to CISA KEV Catalog
2025-05-02

References & Sources

  • [1]NVD - CVE-2024-58136
  • [2]Original Advisory Context
Related Vulnerabilities
CVE-2024-4990CVE-2025-32432

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 days ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
7 views•5 min read
•2 days ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
9 views•7 min read
•2 days ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
8 views•5 min read
•2 days ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
7 views•6 min read
•2 days ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
12 views•7 min read
•2 days ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read