Vendor Phpunit Phpunit Src Util Php Eval-stdin.php Exploit May 2026

Introduction: A Developer’s Convenience Turned Attacker’s Backdoor In the world of web application security, few mistakes are as dangerous as leaving development tools exposed on a production server. Among the most infamous examples of this is a small, seemingly innocuous file: eval-stdin.php , part of the PHPUnit testing framework.

location ~ /vendor/ deny all; return 403; vendor phpunit phpunit src util php eval-stdin.php exploit

https://victim.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php This script accepts PHP code via standard input

If an attacker can make a web server execute this file and send arbitrary PHP code to its stdin , they can achieve Remote Code Execution (RCE) – complete control over the server. The Anatomy of the Exploit (CVE-2017-9841) This vulnerability was formally assigned CVE-2017-9841 . While disclosed in 2017, it remains a persistent problem due to legacy codebases, poor deployment practices, and automated scanning. The Vulnerable Code Snippet Let’s look at the actual source code of eval-stdin.php (simplified for clarity): evaluates it using eval()

192.168.1.100 - - [12/May/2025:10:23:45 +0000] "POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 200 1234 Look for encoded or plaintext PHP functions like system , exec , passthru , shell_exec , file_put_contents , base64_decode , or eval .

This script accepts PHP code via standard input ( stdin ), evaluates it using eval() , and outputs the result. It was intended to execute code snippets in a separate process for isolation during testing.

In a healthy software development lifecycle (SDLC), PHPUnit lives exclusively on a developer’s local machine or within a CI/CD pipeline (like Jenkins, GitLab CI, or GitHub Actions). It should be deployed to a public-facing web server. The Culprit: eval-stdin.php Within the PHPUnit source code, specifically in versions before 4.8.28 and 5.x before 5.6.3, there exists a utility file designed to facilitate a specific type of test called a "Runnable test." The file path is: