Skip to main content

PHPUnit CVE-2026-119193

| EUVDEUVD-2026-113349 MEDIUM
Creation of Temporary File in Directory with Insecure Permissions (CWE-379)
2026-10-29 GitHub_M GHSA-9vw2-f4vp-x7gf
5.4
CVSS 4.0 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Obtain local account on shared-/tmp host
  2. Delivery
    Pre-create /tmp/phpunit-phpt and poll for job file
  3. Exploit
    Developer runs PHPT tests with coverage
  4. Execution
    Swap job file for attacker payload
  5. Persist
    Child process require executes code as developer
  6. Impact
    Steal 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.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.1% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – 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

phpunit 13.4.0, < 13.4.4

Affected Packages

composer phpunit/phpunit fix: 13.4.4
euvd phpunit fix: 13.4.4

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

Vendor (GitHub_M) PRIMARY 5.4 MEDIUM
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
vuln.today AI 6.7 MEDIUM

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).

3.1 AV:L/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H
4.0 AV:L/AC:L/AT:P/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Local
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
Low
User Interaction
Passive
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
High
Vulnerable system: Availability
High
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

Lifecycle Timeline

2
Patch available
Oct 29, 2026 - 20:18 EUVD
CVE Published
Oct 29, 2026 - 19:35 cve.org
MEDIUM 5.4

DescriptionCVE.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

EPSS Score
0.1%
Top 99% exploitable
Prevalence
High
de facto standard PHP testing framework, near-universal PHP dev dependency
Threat Intel
1
1 source
Social Media
1
Sightings
Data Quality
5 sources
Confidence: Medium
EUVD NVD CVE.org EPSS Vulnrichment GHSA CIRCL GitHub VulDB

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.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.1%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation
None
System Exposure· derived
Small
Automatable
No
Human Impact· derived
High
Technical Impact
Total

Priority Score

27
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +27
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy