CVE-2026-24765

7.8 HIGH

📋 TL;DR

This CVE describes a remote code execution vulnerability in PHPUnit's PHPT test execution when code coverage instrumentation is enabled. Attackers with local file write access can place malicious serialized objects in .coverage files, which PHPUnit deserializes without validation during test runs. Organizations using vulnerable PHPUnit versions in CI/CD pipelines, development environments, or with compromised dependencies are affected.

💻 Affected Systems

Products:
  • PHPUnit
Versions: All versions prior to 12.5.8, 11.5.50, 10.5.62, 9.6.33, and 8.5.52
Operating Systems: All operating systems running PHP
Default Config Vulnerable: ✅ No
Notes: Vulnerability only triggers when code coverage instrumentation is enabled for PHPT tests and malicious .coverage files can be placed in the expected location before test execution.

📦 What is this software?

⚠️ Risk & Real-World Impact

🔴

Worst Case

Full remote code execution with the privileges of the PHPUnit process, potentially leading to complete system compromise, data exfiltration, or lateral movement within the environment.

🟠

Likely Case

Code execution within CI/CD pipelines leading to build system compromise, credential theft, or injection of malicious code into production artifacts.

🟢

If Mitigated

Limited impact due to proper CI/CD security controls, ephemeral runners, and restricted file system access preventing malicious .coverage file placement.

🌐 Internet-Facing: LOW
🏢 Internal Only: HIGH

🎯 Exploit Status

Public PoC: ✅ No
Weaponized: LIKELY
Unauthenticated Exploit: ✅ No
Complexity: MEDIUM

Exploitation requires local file write access to the PHPUnit code coverage directory, which can be achieved through CI/CD pipeline compromise, malicious dependencies, or development environment access.

🛠️ Fix & Mitigation

✅ Official Fix

Patch Version: 12.5.8, 11.5.50, 10.5.62, 9.6.33, or 8.5.52 depending on your major version

Vendor Advisory: https://github.com/sebastianbergmann/phpunit/releases

Restart Required: No

Instructions:

1. Identify your PHPUnit major version
2. Update to the patched version: composer require --dev phpunit/phpunit:^12.5.8 (or appropriate version)
3. Run composer update
4. Verify tests still pass with the updated version

🔧 Temporary Workarounds

Disable code coverage for PHPT tests

all

Temporarily disable code coverage instrumentation when running PHPT tests to prevent deserialization of .coverage files

phpunit --no-coverage

Secure code coverage directory permissions

linux

Restrict write access to the directory where PHPUnit stores code coverage files

chmod 755 coverage_directory
chown root:root coverage_directory

🧯 If You Can't Patch

  • Implement strict CI/CD security controls including ephemeral runners, artifact isolation, and branch protection
  • Enforce code review for all changes to test files and dependencies

🔍 How to Verify

Check if Vulnerable:

Check PHPUnit version: phpunit --version and compare against vulnerable versions

Check Version:

phpunit --version

Verify Fix Applied:

Verify version is 12.5.8+, 11.5.50+, 10.5.62+, 9.6.33+, or 8.5.52+ and test that PHPT tests with coverage still work

📡 Detection & Monitoring

Log Indicators:

  • Unexpected .coverage file creation before test execution
  • PHPUnit error messages about anomalous .coverage files in patched versions
  • Unusual process execution from PHPUnit context

Network Indicators:

  • Outbound connections from CI/CD runners to unexpected destinations

SIEM Query:

process.name:php AND command_line:*phpunit* AND (file.path:*/.coverage OR process.parent.name:unusual)

🔗 References

📤 Share & Export