PHPT Vulnerability Exposes CI/CD Pipelines to Remote Code Execution Attacks

The vulnerability resides in the cleanupForCoverage() method, which deserializes code coverage data files without validating input or restricting allowed object classes.

An attacker with local file write access can place a malicious serialized PHP object containing a __wakeup() method into the filesystem.

When PHPUnit processes code coverage during test execution, the unsafe unserialize() function instantiates the malicious object, triggering arbitrary code execution.

The vulnerable code pattern demonstrates the flaw:

textif ($buffer !== false) {
    $coverage = @unserialize($buffer);
}

This implementation deserializes .coverage files without the allowed_classes parameter restriction, creating an unsafe condition that gadget chains can exploit to execute arbitrary operations on the system.

Attack Vector and Impact

The attack requires local file write access to PHPUnit’s code coverage directory, achievable through multiple scenarios.

Most critically, CI/CD pipelines become attack vectors when executing unreviewed pull requests. A malicious contributor can inject a .coverage file alongside test files.

When the CI system runs PHPUnit with code coverage instrumentation enabled, the deserialization triggers automatic code execution without additional user interaction.

This attack class represents a Poisoned Pipeline Execution (PPE) vulnerability, where attackers manipulate CI/CD pipeline execution to execute unauthorized code.

Additional attack paths include supply chain compromises, introducing malicious files into dependencies, or compromised developer machines with shell access to project repositories.

The impact is severe: successful exploitation grants complete system access, enabling attackers to exfiltrate source code, modify build artifacts, inject malicious dependencies, or pivot laterally into connected infrastructure.

Vulnerable PHPUnit versions include 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.

Organizations should verify their PHPUnit installations immediately against these thresholds.

Rather than silently sanitizing untrusted input, PHPUnit’s maintainers implemented an error-based approach.

When a .coverage file exists before test execution, an invariant that should never occur. PHPUnit now emits an explicit error and halts test execution.

This design decision prioritizes visibility and investigation capability, ensuring CI/CD operators detect anomalous filesystem states indicating potential tampering.

The fail-fast semantics prevent silent exploitation while alerting security teams to investigate root causes: unauthorized file placement, environment contamination, or actual attack attempts.

MetricValue
CVE IDCVE-2026-24765
CVSS Score9.8 (High)
Attack VectorLocal

Update PHPUnit immediately to the patched versions. Beyond patching, implement defense-in-depth CI/CD hardening: deploy ephemeral, containerized runners that discard filesystem state between builds; enforce code review requirements before executing external pull requests; implement branch protection rules restricting unreviewed code execution; isolate build artifacts to prevent cross-run contamination; and enforce strict access controls limiting file write permissions to authenticated actors only.

Organizations processing contributions from untrusted sources should prioritize these controls, as they address the broader PPE attack surface extending beyond this specific vulnerability.

Follow us on Google News , LinkedIn and X to Get More Instant UpdatesSet Cyberpress as a Preferred Source in Google.

AnuPriya
AnuPriya
Any Priya is a cybersecurity reporter at Cyber Press, specializing in cyber attacks, dark web monitoring, data breaches, vulnerabilities, and malware. She delivers in-depth analysis on emerging threats and digital security trends.

Trending News

Related Stories