A PHP file in your uploads folder is never supposed to be there
The uploads folder holds pictures and documents. It should never hold code. When it does, that code was almost always put there to run a backdoor.
WordPress writes uploads to wp-content/uploads: images, PDFs, the odd zip. Nothing there is ever meant to be executable PHP. So a .php file in uploads is one of the clearest signals of a compromise there is, and attackers know the folder is writable, rarely watched, and excluded from most integrity checks.
The shapes it takes
- Plain PHP, oddly named. A file like
wp-content/uploads/2026/10/.cache.phporicon-cache.php, holding a web shell that runs whatever a request sends it. - Polyglot images. A real image header followed by PHP, saved as
.ico,.gifor.png. It opens as a picture and runs as code. A favicon named.f4812a.icois a classic. - Payloads inside fonts or compressed blobs. PHP or a zlib-compressed loader tucked into a
.woff,.ttfor.datfile that something else pulls in. - Execution overrides. A
.user.inior.htaccessin an uploads subfolder that setsauto_prepend_file, orAddType application/x-httpd-php .jpg, so the server runs images as PHP.
Finding them by hand
List executable code where only media belongs:
find wp-content/uploads -type f \( -name '*.php*' -o -name '*.phtml' \)
grep -rl '<?php' wp-content/uploads
find wp-content/uploads -name '.user.ini' -o -name '.htaccess'
Anything the first two commands return is worth opening. A .user.ini or .htaccess deep in uploads almost never belongs there. Do not just delete what you find until you have a copy: a backdoor is also evidence of how they got in.
What the R7 radar reads
OwnerTrail treats uploads, and the other folders where code never belongs, as code-free zones. Any PHP there is reported as unexpected. Beyond the name, it reads the file for the shapes malware takes, the same way a human reviewer would:
- PHP after an image or font header (a polyglot), and compressed or encoded payloads.
- Code that runs, decodes or includes whatever a request sends it.
.htaccessand.user.inirules that switch PHP execution back on.- The same reading applied to the files that run before WordPress, such as
wp-config.phpandindex.php, whose contents never leave the file.
On a very large uploads folder it works in short time-slices and picks up where it left off, so even tens of thousands of files get read without stalling the site.
Quarantine, not delete
Finding the file is half the job. With OwnerTrail Pro you move an unexpected file into a sealed vault in one click: it is taken out of the web root into a folder the server refuses to serve or run, under a random name with no extension, and it can be put back if you were wrong. Nothing is destroyed, and the file stops running at once. The files that would take the site down if moved, WordPress's own start-up files and known firewall bootstraps, are never touched.