# CraftCMS Yii Class Injection Remote Code Execution (CVE-2025-32432)

[中文版本(Chinese version)](README.zh-cn.md)

CraftCMS is a flexible and user-friendly content management system built on PHP, widely used for creating customized digital experiences.

CraftCMS versions 3.0.0-RC1 to 3.9.14, 4.0.0-RC1 to 4.14.14, and 5.0.0-RC1 to 5.6.16 are vulnerable to an unauthenticated remote code execution vulnerability in the image transformation feature. The vulnerability exists in the `/actions/assets/generate-transform` endpoint due to insufficient validation of user input. An attacker can exploit this by sending specially crafted requests containing a malicious `__class` parameter that leverages Yii framework's dependency injection container, allowing arbitrary PHP code execution on the server without authentication.

References:

- <https://craftcms.com/knowledge-base/craft-cms-cve-2025-32432>
- <https://www.opswat.com/blog/cve-2025-32432-unauthenticated-remote-code-execution-in-craft-cms>
- <https://github.com/CTY-Research-1/CVE-2025-32432-PoC>

## Vulnerable Environment

Execute the following command to start a CraftCMS server 5.6.16:

```
docker compose up -d
```

After the server is running, you can see the installation page at `http://your-ip:8088/admin/install`. Please follow the instructions to install CraftCMS, the default database address is `db` and the username and password are both `root`.

![](1.png)

## Vulnerability Reproduction

The exploit works through a two-packet chain attack. First, the attacker injects a PHP payload into the server's session file by sending a GET request with the malicious code in a URL parameter. Then, a second POST request to the `/actions/assets/generate-transform` endpoint abuses the Yii framework's `yii\rbac\PhpManager` class through dependency injection to include and execute the session file containing the injected PHP code.

Use the [poc.py](poc.py) script to exploit this vulnerability. Run the script with the `id` command to verify the vulnerability:

```bash
python3 poc.py -u http://your-ip:8088 -c id
```

![](2.png)

As you can see, the `id` and `cat /etc/passwd` commands are executed successfully.

Note that for CraftCMS 3.x versions, the target must have at least one asset uploaded, and you need to enable asset ID handling using the `--need-asset-id` flag. You can either specify a known valid asset ID with `-a/--asset-id` option, or let the script automatically scan for one (up to `--scan-max` limit, default 300). For CraftCMS 4.x and 5.x versions, this requirement may not be necessary. Example for 3.x:

```bash
python3 poc.py -u http://your-ip:8088 -c id --need-asset-id -a 1
```
