In short: A PHP file in the upload folder is a serious warning sign, because only images and documents should be there. Never open the file in the browser; read it as text, check timestamps and owner and search for the file name in the access logs. Usually only empty placeholders such as an index.php without content are harmless; treat everything else as a possible break-in.
Why PHP has no business in the upload folder
Upload folders are for content that visitors or editors upload: images, PDFs, videos. The web server user may write there, otherwise uploads do not work. That is exactly what makes these folders attractive to attackers. Whoever can write files through a vulnerability places them where writing is allowed.
According to the reports available to us, new PHP files in upload or cache folders are among the general warning signs after a break-in. For PHP2Shell there are no confirmed indicators of compromise; a find therefore says nothing about which vulnerability the file came through. How upload functions are built securely is described in Implementing file uploads in PHP securely.
Whether such a file can do harm is decided by the web server configuration. If it executes PHP files in the upload folder, every file placed there becomes a potential remote control. If execution is blocked there, the file remains a foreign object, but initially without effect. Many installations never set up this block.
How does a PHP file get into the upload folder?
For the assessment, it helps to know the possible routes. Each leads to different follow-up questions.
| Route | Typical background | Follow-up question |
|---|---|---|
| Insecure upload form | Check only of the extension or of the type reported by the browser | Which forms accept files? |
| Vulnerability in a plugin or theme | Known weakness in an outdated extension | Which extensions are outdated? |
| Stolen credentials | Admin, FTP or hosting account | Which logins were there recently? |
| Code execution through a vulnerability | for example in the interpreter, as possible with PHP2Shell | Was PHP vulnerable during the period? |
| Legitimate plugin | Placeholder, rarely cache files | Does the file belong to the original package? |
Several routes can come together. An attacker who executes code through a vulnerability may place the file only to return more conveniently later.
Listing the finds systematically
Before you assess an individual file, get an overview. The commands only read. Paths are examples for WordPress; for other systems, adjust the upload path.
# PHP-like files in the upload folder with size, owner, mtime and ctime
find /var/www/html/wp-content/uploads -type f \
\( -iname "*.php*" -o -iname "*.phtml" -o -iname "*.phar" -o -iname ".htaccess" -o -iname ".user.ini" \) \
-printf '%s Bytes %u m:%T+ c:%C+ %p\n'
# Determine file type by content instead of extension (images with PHP content stand out)
find /var/www/html/wp-content/uploads -type f -newermt "2026-10-17" -exec file {} + | grep -viE "image|pdf|video|audio"
Other systems use other writable folders, such as fileadmin in TYPO3, images in Joomla or the media folder under public in Shopware 6. Cache and temp directories of the application are added. With multisite installations and several websites on one server, there are correspondingly many upload folders; each belongs in the search.
.htaccess and .user.ini files in the upload folder are also suspicious. They can be used to switch PHP execution back on in that folder or to alter the configuration.
PHP file in the uploads folder: interpreting the find correctly
Not every hit is equally serious. The classification below helps with the first assessment. It does not replace a thorough investigation.
| Finding | First classification |
|---|---|
index.php with zero bytes or only a comment |
usually a placeholder against directory listing, compare with the plugin |
| PHP file with content in a monthly folder | high suspicion |
Double extension such as bild.jpg.php or .php.png |
high suspicion, typical camouflage |
Image that contains PHP code according to file |
high suspicion, can be executed through inclusion |
.htaccess or .user.ini in the upload folder |
suspicion, check the configuration |
| File belongs to the web server user, ctime after 17 Oct | fits a break-in through the website |
Read suspicious files only as text, for example with head -c 2000 datei.php or less. Very long lines, encoded strings and function names such as eval or base64_decode stand out. How to recognize obfuscated code is shown in Recognizing obfuscated PHP code.
Was the file called? A look into the log
The most important question after the find is: did anyone use the file? The answer is in the web server's access logs. Search for the file name, including in archived logs.
# Calls to the suspicious file in current and compressed logs (name as an example)
grep -h "uploads/2026/10/thumb.php" /var/log/nginx/access.log* 2>/dev/null
zgrep -h "uploads/2026/10/thumb.php" /var/log/nginx/access.log*.gz 2>/dev/null
# Only successful calls with IP address and time
grep -h "uploads/2026/10/thumb.php" /var/log/nginx/access.log* | awk '$9 == 200 {print $1, $4, $6, $7}'
Many successful POST requests from a few addresses point to active use as a webshell. No hits does not automatically mean all clear, because logs may have been rotated, deleted or be incomplete. If the website runs behind a CDN or a proxy, further logs are kept there; with shared hosting, the hoster usually provides the access logs in the customer area. Also watch for requests to other new files from the same addresses, because they often lead to further components. Keep logs from 20 October onward. How to evaluate logs thoroughly is covered in the guide Evaluating web server logs after an attack.
If the log shows successful calls to an unknown PHP file, assume a break-in. Secure the file and logs, restrict access to the server and check whether personal data may be affected.
After the assessment: the right order
- Secure: Copy the file with checksum and timestamps, secure the logs.
- Clarify the origin: Check upload forms, plugins and the period before the find.
- Look for further components: additional files, cron jobs, new admin accounts.
- Block execution: Forbid PHP in the upload folder at web server level, as described in the article Forbidding PHP execution in upload folders.
- Clean up and change credentials: only then remove the file and renew all passwords.
How does PHP SOS help?
- Assess the find: We examine the file without executing it and classify it.
- Clarify use: We evaluate the logs and reconstruct who called the file and when.
- Clean up completely: With malware removal, we search for all components, close the cause and change the credentials.
- Prevent repetition: We block PHP execution in writable folders and monitor new files.
Frequently asked questions
Is every PHP file in the upload folder dangerous?
Not every one. Some plugins place an empty index.php so that the folder contents are not listed. Treat everything else, especially files with content, an unusual name or a double extension, as a suspected case.
May I open the suspicious file in the browser?
No. Calling it through the website executes the code. Read the file only as text on the server or in a copy, for example with less or head.
How do I find out whether the file was used?
Search for the file name in the web server's access logs. Requests with status 200 and the POST method show that the file was called. The associated IP addresses and times help with further investigation.
Is it enough to delete the file and block PHP in the upload folder?
Both are necessary but not sufficient. Also clarify how the file got there, look for further components and change the credentials. Otherwise the attacker returns the same way.