Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mchiasson's avatar

How do I keep getting hacked on PHPUnit?

I need to secure my install a bit better as it was installed as a subdomain of my root. I do have .htaccess restrictions to block .ENV access but still keep manage to see a hacked page popup once in a while on my server monitoring. Each time it looks like a PHP Webshell gets uploaded.

When looking at my raw access logs it shows a lot of different requests to PHPUnit and I'm curious if that is the flaw in my system. My Env is set for App_Debug=False. Below is a snippit of my logs, you can see them sending get/post requests to alpha.php in phpunit and then also eventually they have access to a phpshell of '/wp-includes/css/dist/list-reusable-blocks/pwjs4ahasd.php' in an above level wordpress install.

109.127.13.152 - - [29/Jun/2019:19:20:30 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 146160 "http://MYDOMAIN.com/portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:32 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 10536 "http://MYDOMAIN.com/portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:34 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 3141 "http://MYDOMAIN.com/portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:41 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 3909 "http://MYDOMAIN.com/portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:46 -0400] "GET /portal.MYDOMAIN.com/MYDOMAIN-back-office/vendor/knplabs/knp-snappy/src/Knp/new.php HTTP/1.1" 404 73885 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:48 -0400] "GET /wp-includes/css/dist/list-reusable-blocks/pwjs4ahasd.php HTTP/1.1" 200 319 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:20:52 -0400] "POST /wp-includes/css/dist/list-reusable-blocks/pwjs4ahasd.php HTTP/1.1" 200 8038 "http://www.MYDOMAIN.com/wp-includes/css/dist/list-reusable-blocks/pwjs4ahasd.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:21:33 -0400] "GET / HTTP/1.1" 301 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:21:59 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 11910 "http://MYDOMAIN.com/portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:22:15 -0400] "GET /wp-includes/css/dist/list-reusable-blocks/pwjs4ahasd.php HTTP/1.1" 200 8038 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0"
109.127.13.152 - - [29/Jun/2019:19:22:25 -0400] "POST /portal.MYDOMAIN.com/MYDOMAIN-back-office//vendor/phpunit/phpunit/src/Util/PHP/alfa.php HTTP/1.1" 200 7199 " ```
Any suggestions? This weekend I'll go separate these domains into different cPanel directories.
0 likes
10 replies
diegoaurino's avatar

Hello, @mchiasson !

It is hard to say based on the information you are providing.

What do you mean by ".htaccess restrictions to block .ENV"? You should expose only the public folder and properly set the permissions for this folder. That is the most basic thing you can do.

Also, from a sysadmin point of view, relying only on a custom .htaccess configuration is a bad idea. You need to properly set up your web server (Apache or Nginx) to secure the Laravel root directory and only expose the public folder.

If the attacker has access to your vendor folder, he can use PHPUnit to trigger any PHP code via POST request.

I don't believe the problem is with PHPUnit however.

It is also important to upgrade your entire framework from time to time.

Hope this helps. Let me know.

Snapey's avatar

perhaps its a known vulnerability with alfanet as the script that appears first is alfa.php

But anyway, @diegoaurino tells you. Don't mess with the application layout. Your framework should not be in a public place.

dylboy's avatar

As a note i have this happen on a couple of sites as well . always vendor/phpunit/phpunit/src/Util/PHP/unit.php

steveleblanc's avatar

My sites are getting hacked through phpunit several times over the last year. So I am removing phpunit from each site now

jove's avatar

I don't see a reason to install phpunit in production anyways.

2 likes
willvincent's avatar

If PHPUnit is the vulnerability, easy fix -- remove phpunit.

PHPUnit is a dev package requirement, and should be installed as such. No dev packages need nor should be installed in production.

mchiasson's avatar

This is a solid point. Out of curiosity when using Git how to I exclude 'require dev'? When I make the changes to my local dev environment I usually just add all with Git which would then apply same composer changes to my production server.

What is the better method here? I usually exclude .ENV file from Git, do people usually exclude composer and go manually adjust those on production also?

Thanks.

Sinnbeck's avatar

You composer file should be fine but on production you can install excluding dev dependencies

composer install --no-dev
2 likes
jove's avatar

Yea, never run composer install in production without --no-dev you might get something you really don't want in a production system.

Please or to participate in this conversation.