CVE-2017-9841 — PHPUnit Command Injection Vulnerability

CVE-2017-9841

PHPUnit — eval-stdin.php Executes Arbitrary PHP from HTTP POST Body When Vendor Directory Is Web-Accessible; CRITICAL 9.8; Fixed in PHPUnit 4.8.28 / 5.6.3

What Is PHPUnit and the eval-stdin.php File?

PHPUnit is the standard unit testing framework for PHP, installed as a development dependency via Composer into the vendor/ directory of PHP projects. Older PHPUnit versions shipped with a utility file — vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php — that reads PHP code from php://input (the raw HTTP request body) and evaluates it. This file exists to support testing PHP's eval behavior in an isolated subprocess. When a project deploys its vendor/ directory to a web server without restricting HTTP access to it, this file becomes a no-authentication remote PHP execution endpoint accessible to anyone on the internet.

Overview

Actively Exploited. This vulnerability has been added to CISA's Known Exploited Vulnerabilities (KEV) Catalog on February 15, 2022. Federal agencies are required to apply mitigations per BOD 22-01.

CVE-2017-9841 is a code injection vulnerability (CWE-94) in PHPUnit caused by a development utility file (eval-stdin.php) being deployed to and accessible on production web servers. The file contains eval('?>' . file_get_contents('php://input')); — any HTTP POST request with PHP code in the body executes that code in the context of the web server process. No authentication, no special headers, and no application knowledge are required. The vulnerability is in PHPUnit versions before 4.8.28 and 5.x before 5.6.3; the fix removed eval-stdin.php. CISA added CVE-2017-9841 to the KEV catalog in February 2022.

Affected Versions

PHPUnit Version Status
4.x before 4.8.28 Vulnerable — contains eval-stdin.php
5.x before 5.6.3 Vulnerable — contains eval-stdin.php
4.8.28+ / 5.6.3+ Fixed — eval-stdin.php removed
6.x and later Not affected — file never present

Also affected: Any application where the vendor/ directory (or specifically vendor/phpunit/) is accessible via HTTP, regardless of whether the application itself is up to date — the vulnerable file may remain from a historical install.

Technical Details

Root Cause: Development Utility File Exposed on Production Server

CVE-2017-9841 is a code injection vulnerability (CWE-94) caused by a testing utility file being deployed to a production web-accessible directory. The vulnerable file eval-stdin.php contains:

<?php
eval('?>' . file_get_contents('php://input'));

This single line reads the raw HTTP POST body and evaluates it as PHP code. An attacker simply POSTs arbitrary PHP to the file's URL:

POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

<?php system('id'); ?>

The PHP executes with the privileges of the web server process (typically www-data or similar) and returns output in the response.

Root deployment mistake: The standard PHP Composer workflow installs all dependencies — including development-only packages like PHPUnit — into vendor/. Production deployments should either:

  • Exclude dev dependencies (composer install --no-dev), or
  • Block HTTP access to the vendor/ directory via web server configuration

When neither of these is done, every file in vendor/ becomes web-accessible.

Attack Characteristics

Attribute Detail
Attack Vector Network — HTTP POST to eval-stdin.php URL
Authentication None
Request complexity Single HTTP POST with PHP in body
Execution As web server process user
Detection Access to /vendor/phpunit/ in web logs

Discovery

Reported in 2017; the file was removed in PHPUnit 4.8.28 and 5.6.3. The issue became widely known when automated scanners began targeting /vendor/phpunit/ paths at scale.

Exploitation Context

  • Mass automated scanning: CVE-2017-9841 is trivial to exploit and scan for — attackers run automated tools against large swaths of the internet probing for /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php; successful hits are immediately weaponized for cryptominer deployment, web shells, and lateral movement
  • Development-to-production leakage: The vulnerability exposes a systemic problem in PHP deployment — Composer installs both production and development dependencies unless --no-dev is specified; many teams install all packages in production for convenience and do not restrict vendor/ directory access
  • Supply chain deployment risk: Even applications that upgrade PHPUnit may retain the vulnerable file if they use composer update while the old version's files remain in vendor/; proper remediation requires verifying the file is absent, not just checking the installed version
  • Persistent scanning target: Years after the 2017 patch, CVE-2017-9841 remains one of the most commonly scanned-for vulnerabilities in PHP web applications; CISA KEV addition in 2022 reflects continued successful exploitation against unpatched or improperly configured deployments
  • CISA KEV (2022): Added February 15, 2022 reflecting active exploitation of exposed PHPUnit vendor directories

Remediation

CISA BOD 22-01 Deadline: August 15, 2022. Apply updates per vendor instructions.
  1. Remove the eval-stdin.php file — immediately check for and delete vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php from all web servers; this eliminates the vulnerability regardless of PHPUnit version.

  2. Upgrade PHPUnit to 4.8.28+ or 5.6.3+ — updated versions no longer include eval-stdin.php; use composer require --dev phpunit/phpunit:^5.6.3 or equivalent.

  3. Install without dev dependencies in production — run composer install --no-dev in production environments; this excludes PHPUnit and other development packages from being deployed at all.

  4. Block HTTP access to the vendor directory — configure the web server to deny all requests to /vendor/: for Nginx use location /vendor/ { deny all; }; for Apache add Deny from all in a .htaccess or Directory block for the vendor path.

  5. Scan for exposed vendor directories — use a vulnerability scanner or custom HTTP probe to check all PHP web applications for accessible /vendor/ paths; include this check in regular web application security testing.

  6. Audit web server logs — search access logs for eval-stdin.php requests; any hits indicate exploitation attempts and may indicate compromise requiring incident response.

Key Details

PropertyValue
CVE ID CVE-2017-9841
Vendor / Product PHPUnit — PHPUnit
NVD Published2017-06-27
NVD Last Modified2025-10-22
CVSS 3.1 Score9.8
CVSS 3.1 VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
SeverityCRITICAL
CWE CWE-94 — Improper Control of Generation of Code ('Code Injection') find similar ↗
CISA KEV Added2022-02-15
CISA KEV Deadline2022-08-15
Known Ransomware Use No

CVSS 3.1 Breakdown

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Required Action

CISA BOD 22-01 Deadline: 2022-08-15. Apply updates per vendor instructions.

Timeline

DateEvent
2017-02-01PHPUnit 4.8.28 and 5.6.3 released, removing eval-stdin.php
2017-06-27CVE-2017-9841 published by NVD
2022-02-15Added to CISA Known Exploited Vulnerabilities catalog
2022-08-15CISA BOD 22-01 remediation deadline

References

ResourceType
NVD — CVE-2017-9841 Vulnerability Database
CISA KEV Catalog Entry US Government
PHPUnit 4.8 Changelog — CVE-2017-9841 fix in 4.8.28 Vendor Advisory