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
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-devis specified; many teams install all packages in production for convenience and do not restrictvendor/directory access - Supply chain deployment risk: Even applications that upgrade PHPUnit may retain the vulnerable file if they use
composer updatewhile the old version's files remain invendor/; 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
-
Remove the eval-stdin.php file — immediately check for and delete
vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.phpfrom all web servers; this eliminates the vulnerability regardless of PHPUnit version. -
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.3or equivalent. -
Install without dev dependencies in production — run
composer install --no-devin production environments; this excludes PHPUnit and other development packages from being deployed at all. -
Block HTTP access to the vendor directory — configure the web server to deny all requests to
/vendor/: for Nginx uselocation /vendor/ { deny all; }; for Apache addDeny from allin a.htaccessorDirectoryblock for the vendor path. -
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. -
Audit web server logs — search access logs for
eval-stdin.phprequests; any hits indicate exploitation attempts and may indicate compromise requiring incident response.
Key Details
| Property | Value |
|---|---|
| CVE ID | CVE-2017-9841 |
| Vendor / Product | PHPUnit — PHPUnit |
| NVD Published | 2017-06-27 |
| NVD Last Modified | 2025-10-22 |
| CVSS 3.1 Score | 9.8 |
| CVSS 3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Severity | CRITICAL |
| CWE | CWE-94 — Improper Control of Generation of Code ('Code Injection') find similar ↗ |
| CISA KEV Added | 2022-02-15 |
| CISA KEV Deadline | 2022-08-15 |
| Known Ransomware Use | No |
CVSS 3.1 Breakdown
Required Action
Timeline
| Date | Event |
|---|---|
| 2017-02-01 | PHPUnit 4.8.28 and 5.6.3 released, removing eval-stdin.php |
| 2017-06-27 | CVE-2017-9841 published by NVD |
| 2022-02-15 | Added to CISA Known Exploited Vulnerabilities catalog |
| 2022-08-15 | CISA BOD 22-01 remediation deadline |
References
| Resource | Type |
|---|---|
| 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 |