The cleanupForCoverage() method, which deserializes code coverage data files without verifying input or limiting permitted object classes, is the source of the vulnerability This article explores phpunit code coverage. . A malicious serialized PHP object with a __wakeup() method can be inserted into the filesystem by an attacker with local file write access.

The malicious object is instantiated by the unsafe unserialize() function, which causes arbitrary code execution when PHPUnit processes code coverage during test execution. The vulnerability is illustrated by the following code pattern: textif ($buffer !== false) { $coverage = @unserialize($buffer); } This implementation deserializes.coverage files without the allowed_classes parameter restriction, resulting in a dangerous situation that device chains can take advantage of to carry out arbitrary system operations. Impact and Attack Vector The attack necessitates local file write access to the code coverage directory of PHPUnit, which can be accomplished in a number of ways.

Most importantly, when unreviewed pull requests are executed, CI/CD pipelines become attack vectors. Alongside test files, a malicious contributor may insert a.coverage file. Deserialization initiates automatic code execution without further user input when the CI system runs PHPUnit with code coverage instrumentation enabled.

This attack class is an example of a Poisoned Pipeline Execution (PPE) vulnerability, which allows attackers to alter the execution of CI/CD pipelines in order to run unauthorized code. Supply chain breaches, the insertion of malicious files into dependencies, and compromised developer machines with shell access to project repositories are further attack avenues. The consequences are dire: if an exploit is successful, full system access is granted, allowing attackers to change build artifacts, insert malicious dependencies, exfiltrate source code, or pivot laterally into linked infrastructure.

PHPUnit versions 8.5.51 and earlier, 9.6.32 and earlier, 10.5.61 and earlier, 11.5.49 and earlier, and 12.5.7 and earlier are vulnerable. Businesses should check their PHPUnit installations against these thresholds right away. The maintainers of PHPUnit adopted an error-based method instead of silently cleaning untrusted input.

An invariant that should never happen is when a.coverage file is present prior to test execution. PHPUnit now stops the test's execution and emits an explicit error. In order to ensure that CI/CD operators identify unusual filesystem states that may indicate tampering, this design choice places a high priority on visibility and investigation capability. While warning security teams to look into the underlying causes—unauthorized file placement, environmental contamination, or actual attack attempts—the fail-fast semantics stop silent exploitation.

Metric Value CVE ID CVE-2026-24765 CVSS Score 9.8 (High) Attack Vector Local Update PHPUnit to the updated versions right away. Implement defense-in-depth CI/CD hardening in addition to patching: use ephemeral, containerized runners that discard filesystem state in between builds; enforce code review requirements prior to executing external pull requests; implement branch protection rules that limit the execution of unreviewed code; isolate build artifacts to prevent cross-run contamination; and enforce stringent access controls that restrict file write permissions to authenticated actors only. These controls should be given top priority by organizations handling contributions from unreliable sources because they address the larger PPE attack surface that goes beyond this particular vulnerability.