
- "Why would a web server execute .phtml as PHP?"
Apache (a very common web server) uses a configuration file where admins specify which file extensions should be handled by the PHP interpreter. A common, genuinely widespread config line looks like: Apache Admins often add multiple extensions to this line — historically, .phtml was a real, legitimate convention some PHP frameworks used (mixing PHP and HTML, hence "phtml"), so server configs supported it for genuine compatibility reasons, not by accident. The problem isn't that this is irrational — it's that the upload validator (written by one developer, checking .php specifically) and the server config (set up by someone else, possibly years earlier, supporting multiple legitimate PHP-related extensions for compatibility) were never cross-checked against each other. Each piece made sense on its own; nobody connected the two.
2. "Some websites accept PHP files in comment/image uploads"
profile pictures, comment attachments, document uploads — genuinely useful features. The intended design almost always assumes: "users will upload images (.jpg, .png) or documents (.pdf), never executable code."
Where it goes wrong: the validator checks the file extension (.jpg, .png allowed) or sometimes even checks the file's declared MIME type — but extensions and MIME types are just labels the uploader provides, not proof of what the file actually contains. You can rename shell.php to shell.jpg, and a naive validator that only checks the extension string will wave it through, even though the actual file content is executable PHP code, not image data.
So the vulnerability isn't "the site allows uploads" — uploads are a legitimate feature. The vulnerability is: the validation only checked a label the attacker controls, instead of verifying the actual file content matches what's claimed
3. "Is there a fix, given .phtml (and similar) can still execute?"
Yes — several real, layered defenses
1. Validate actual file content, not just the extension/label Check the file's real binary signature ("magic bytes") — genuine JPEG files start with specific bytes (FF D8 FF), genuine PNGs start with 89 50 4E 47, etc. A file claiming to be .jpg but containing PHP source code won't match that signature, and gets rejected regardless of what extension the attacker chose.
2. Store uploads outside the web-servable directory, or disable execution in the upload folder Even if a malicious file somehow gets through, if the folder where uploads are stored is configured to never execute code (just serve raw files, or isn't even reachable by direct URL at all), the file sitting there is harmless — it can't run, no matter what it contains. This is genuinely one of the strongest fixes, because it doesn't depend on catching every clever bypass — it removes the ability to execute entirely, structurally.
3. Rename uploaded files to a fixed, random name/extension the system controls Instead of trusting the uploader's filename/extension at all, the server generates its own filename (like a random UUID) with a server-chosen, safe extension based on the actual detected content type — not whatever the attacker originally named it. This sidesteps the whole .php vs .phtml vs .php5 guessing game entirely, since the attacker never gets to choose the final extension.
4. Serve uploaded files from a completely separate domain/subdomain with no code-execution capability at all Many real platforms (image hosts, cloud storage) serve user uploads from a totally separate domain specifically configured to only ever serve static files, never execute anything — so even a successful malicious upload has nowhere capable of running it.
About the author
- just a simple guy
Comments
Join the discussionNo comments yet. Be the first to comment.




