Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain local account on shared-/tmp host
-
DeliveryPre-create /tmp/phpunit-phpt and poll for job file
-
ExploitDeveloper runs PHPT tests with coverage
-
ExecutionSwap job file for attacker payload
-
PersistChild process require executes code as developer
-
ImpactSteal developer's source, credentials, SSH keys
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V5 - File Handling Temp file permissions
|
| Exploitation Conditions | All of the following must hold: PHPUnit version 13.4.0-13.4.3 is in use; PHPT tests are executed with code coverage collection enabled (requires a coverage driver such as PCOV or Xdebug); sys_get_temp_dir() is shared between users - e.g. a shared /tmp on Linux/Unix without systemd PrivateTmp, pam_namespace, or a per-user TMPDIR; the attacker has a local account (or controls a process/service running as another user) on the same host; and the attacker creates /tmp/phpunit-phpt before the developer's first coverage run since temp was last cleaned, then wins the race to replace the job file before the child process requires it. Exploitation is LIMITED by: required victim action (a developer must actually run PHPT tests with coverage), the timing/race window, the need for a pre-existing local account, and configuration dependence. Explicitly NOT affected: PHPUnit 12.5 and earlier (temp files written next to the PHPT file), default macOS and Windows (per-user temp directories), and single-user environments such as containers or ephemeral single-user CI runners where no other user can create files in the temp path. |
| Impact | This is a genuine but narrowly-scoped local privilege-escalation issue (CWE-379), not a high-severity remote threat. The supplied CVSS 4.0 vector (AV:L/AC:L/AT:P/PR:L/UI:P, base 5.4 Medium) correctly reflects that exploitation is local, requires an existing low-privileged account (PR:L), depends on a specific attack precondition/timing window (AT:P - the attacker must create the directory before the developer and win a race to swap the job file), and requires the victim to take action (UI:P - a developer must run PHPT tests with code coverage). Impact is high (VC:H/VI:H/VA:H) because successful exploitation yields arbitrary code execution as the developer. The vuln.today decision label is 'this_month' (not act_now/emergency), consistent with a real-but-non-urgent fix. No EPSS score and no CISA KEV entry were provided in the input, and there is no indication of active exploitation. However, the official GitHub Security Advisory (GHSA-9vw2-f4vp-x7gf) publishes a complete, step-by-step working proof-of-concept (an attacker script plus full reproduction), so exploit knowledge is fully public even though real-world exploitation is not confirmed. The vendor itself rates likelihood as low because of the stacked prerequisites. Net: patch within the normal cycle; the stacked local/timing/configuration conditions keep real-world risk well below what the 'RCE' tag alone might suggest. |
| Exploit ScenarioDerived | On a Linux build or development host where /tmp is shared between users, a logged-in attacker (e.g. mallory) pre-creates the predictable /tmp/phpunit-phpt directory and runs a watcher that polls for the job file. When the developer (alice) runs PHPT tests with code coverage, the attacker renames the generated phpunit_phpt_<random>.php job file and drops a malicious replacement, which the child process then executes via require with alice's privileges while the test still reports success. A full working PoC for exactly this is published in the GitHub advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 29, 2026
Local code execution against developers running PHPT tests with code coverage in PHPUnit 13.4.0 through 13.4.3, where the framework writes each PHPT job file into a fixed-name phpunit-phpt directory under sys_get_temp_dir() and reuses that directory even if another local user created it first. An attacker holding a local account on the same host can pre-create the directory, wait for a job file to appear, swap in their own code, and have it executed with the developer's privileges when the child process requires the file - while the test still reports OK and the coverage report looks complete. Exploitation requires a shared temporary path (a shared /tmp on Linux/Unix without per-user TMPDIR, systemd PrivateTmp or pam_namespace), the victim actually running PHPT tests with a coverage driver such as PCOV or Xdebug, and winning the timing window; there is no CISA KEV entry and no confirmed active exploitation, though the vendor advisory documents a step-by-step proof-of-concept reproduction.
RemediationAI
Upgrade to PHPUnit 13.4.4 (released at https://github.com/sebastianbergmann/phpunit/releases/tag/13.4.4), which creates the PHPT coverage temporary directory with an unpredictable name and 0700 permissions and refuses to reuse an existing directory. Where an immediate upgrade is not possible, the vulnerability can only be exercised through a shared temporary path, so isolate the temporary directory per user or per job: set a private TMPDIR for the account running the tests, enable systemd PrivateTmp or pam_namespace for the build/development shell, or run PHPT coverage in a single-user container or ephemeral CI runner where no other account, including service accounts, can create files in the temp path. These measures remove the attacker's ability to pre-create /tmp/phpunit-phpt, but they rely on correct configuration of each environment and do not fix the underlying reuse of an attacker-owned directory, so updating remains the complete fix; note also that a directory already created by another user must be removed for the isolation to be effective. Fix commit: https://github.com/sebastianbergmann/phpunit/commit/ae31c78a86e9d6c641497bacf47462d7bb7d7f34
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in composer, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The flaw is CWE-379 (creation of a temporary file in a directory with incorrect permissions). Since 13.4.0, PHPUnit's TestCase::coverageFilesDirectory() in src/Runner/Phpt/TestCase.php returned sys_get_temp_dir() . '/phpunit-phpt', and the constructor placed phpunit_phpt_<random>.php (the job file) and phpunit_phpt_<random>.coverage inside it. Filesystem::createDirectory() returned true when the directory already existed without checking its owner or mode, and created it with mode 0777 (subject to umask) otherwise. The owner of a directory can list, rename, delete and replace every file inside it regardless of file ownership, and because the directory carried no sticky bit, Linux's fs.protected_regular and fs.protected_symlinks protections do not apply, so the random filename component provides no real defence: the attacker renames the job file and places a payload that requires the original, keeping the test passing. The .coverage file can be substituted the same way, allowing falsification of coverage data since cleanupForCoverage() only unserializes PHPUnit's raw code coverage class. Prior versions (12.5 and earlier) wrote these temporary files next to the PHPT test file and are unaffected; macOS and Windows use per-user temporary directories by default and are unaffected in their default configuration. The 13.4.4 fix replaces the static helper with a per-instance directory named phpunit-phpt-<hex random> created via mkdir(..., 0o700) that fails when the path already exists, and removes the directory afterwards.
Know when Phpunit gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Local attacker with an existing account (AV:L/PR:L) must win a timing race on a shared temp dir (AC:H) and the developer must run coverage tests (UI:R); require yields full code execution (C/I/A:H).
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
PHPUnit is a testing framework for PHP. From 13.4.0 until 13.4.4, the TestCase::coverageFilesDirectory() logic in src/Runner/Phpt/TestCase.php creates temporary files for PHPT code coverage in a predictable phpunit-phpt directory under sys_get_temp_dir() and reuses that directory without verifying its ownership or permissions. On multi-user systems with a shared temporary path, a local attacker who creates the directory before the developer runs PHPT tests with code coverage can replace the generated job file before the child process executes it with require, allowing arbitrary code execution with the developer's privileges while the test and coverage report appear successful. PHPUnit 12.5 and earlier, default macOS and Windows configurations with per-user temporary directories, and single-user environments where another user cannot create files in the temporary path are not affected. This issue is fixed in 13.4.4.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Unsafe deserialization in PHPUnit versions before 8.5.52, 9.6.33, 10.5.62, 11.5.50, and 12.5.8 allows local attackers to
Arbitrary PHP directive injection in PHPUnit 12.5.21 and 13.1.5 enables local attackers with write access to phpunit.xml
Cross-site scripting (XSS) vulnerability in the PHPUnit extension before 3.5.15 for TYPO3 allows remote attackers to inj
EUVD-2026-113349
GHSA-9vw2-f4vp-x7gf
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB